c# - que - material junta andalucia
¿La creación de una instancia de una clase secundaria crea una instancia de la clase principal? (7)
Soy nuevo en C #, y quería saber que si creo una instancia de una clase secundaria, ¿también crea automáticamente una instancia de la clase principal o qué?
Aquí está mi código:
class Program
{
public class ParentClass
{
public ParentClass()
{
Console.WriteLine("ChildClass uses my Ctor ");
}
}
public class ChildClass : ParentClass
{
public ChildClass()
{
Console.WriteLine("SaySomething");
}
}
public static void Main()
{
ChildClass child = new ChildClass();
}
}
¿También crea automáticamente una instancia de la clase Parent?
No es una instancia separada ; ChildClass
es una instancia de ParentClass
, cuando se habla de herencia.
En palabras, esto es como:
Al crear un perro, ¿también creamos una instancia de un animal?
No creamos un perro y (por separado) creamos un animal; El perro es la instancia animal. Y si creamos un caniche, el caniche es el perro y es el animal.
Digamos que tienes clase de padres de Coffee
y clase de niños Cappucino
class Coffee {}
class Cappucino : Coffee {}
Al emitir un new Cappucino()
, se crea una instancia para Cappucino. Cappucino es en realidad café y las propiedades del café se heredan de Cappucino.
No se crea ninguna instancia separada para el café.
Cappucino lleva las características del café por herencia.
Hablando específicamente sobre su código:
class Program
{
public class ParentClass
{
public ParentClass()
{
Console.WriteLine("ParentClass constructor is called");
}
}
public class ChildClass : ParentClass
{
public ChildClass()
{
Console.WriteLine("ChildClassConstructor is called");
}
}
public static void Main()
{
//will print that the Parent ctor is called, followed by printing that the child ctor is called
ChildClass child = new ChildClass();
//will print that the Parent ctor is called, followed by printing that the child ctor is called
ParentClass childinparentbox = new ChildClass();
//will print that the Parent ctor is called
ParentClass parent = new ParentClass();
//At this point there are 3 object instances in memory
//by the way, this can''t be done. Can''t store a parent in a child: a parent is-not-a child
ChildClass parentinchildbox = new ParentClass();
}
}
Cambié los mensajes para hacerlos relevantes al punto que se hizo:
Un constructor es solo un método que se llama a la fuerza cada vez que se crea un nuevo objeto. Lo usa para configurar el nuevo objeto para su uso, inicializar propiedades, etc. Las clases son jerárquicas en C #: todo es siempre una subclase de algo, a veces Objeto. Su parentClass es un hijo de Object, simplemente no lo dice. Su hijo es declarado hijo de padre
Como han señalado otros, no obtiene varias instancias de objetos cuando utiliza new
, obtiene una instancia de lo que sea que se le pidió que creara. Las clases secundarias siempre se pueden denominar / "almacenar dentro de" una variable que se declara como un tipo principal. Esto se debe a que las cosas tienen una relación "is-a" en la dirección de Child -> Parent. Un perro es un animal, un gato es un animal, un animal es un objeto. No tienen una relación en la dirección opuesta. No se puede decir universalmente que un Coche es un Ferrari, o un Animal es un Perro.
Entonces, las cosas hacen retroceder a la jerarquía, y puedes almacenar un Gato o un Perro dentro de una variable declarada para albergar un Animal. El animal puede tener un método GetNumberOfLegs (), que informa el número de patas. Gato y perro volverían cada uno 4, Mono devolvería 2.
Uno de los principios clave de la programación orientada a objetos es que puede referirse a cosas de una manera genérica; Todos los animales tienen cierta cantidad de patas. Si es un Gato / Perro almacenado en el Animal, GetNumberOfLegs () devuelve 4, si es un Mono, devuelve 2 .. Pero no necesitas saber específicamente que es un gato, un perro, un mono, si todo lo que te interesa es El número de piernas. Esto se cubrirá más en las próximas conferencias, por lo que no necesito profundizar en esto aquí. Pongo este detalle como una explicación de por qué podríamos incluso querer tener una jerarquía, tener un Animal, crear un Perro y almacenarlo dentro de una variable de tipo Animal. Lo hacemos porque a menudo queremos referirnos a las cosas de manera genérica porque no nos interesan los detalles específicos; Definimos las cosas genéricas que nos importan, y las cosas específicas encajan en el molde. Puedes conducir un coche; no es necesario que se le enseñe específicamente a conducir un Ford o un Chevrolet; tienen el volante y los pedales en el mismo lugar / disposición. Puede operar la interfaz genérica. No importa cómo se implemente la dirección (hidráulica, piñón y cremallera, brazo Pitman), solo le importa que cuando gire el volante "así", el automóvil vaya "así".
Volviendo a lo que pediste:
Como Child is-a Parent is-a Object, cuando crea un nuevo Child, verá una impresión que indica que se llamó al constructor principal y otra que indica que se llamó al constructor secundario. Esto no indica que se hayan creado 2 objetos en la memoria de la computadora; se llama a los constructores en orden de avance (de raíz a punta) para todo en la jerarquía que comienza con Objeto, luego Padre, luego Hijo. Es así porque lo primero en el código de cualquier constructor, es una llamada a un constructor principal relevante. Lo primero en el código de ese constructor, es una llamada a su padre
Entonces, el tiempo de ejecución comienza en el Niño, luego va hacia el padre, el abuelo, el bisabuelo, hasta la cima de la ascendencia, luego regresa hacia abajo, ejecutando el resto del código en cada constructor en orden, de arriba a abajo. . Esta es la razón por la que ve la copia impresa a la que se llamó al constructor principal, luego ve a la secundaria
Es todo un mismo objeto, es múltiples llamadas a métodos. Al ver dos impresiones no es indicativo de dos objetos en la memoria, es un objeto con dos métodos (dos métodos de construcción) que se han llamado en un orden recursivo
La respuesta real a su pregunta es
''No'', es una instancia de la clase Child, no del Parent.
Pero si su pregunta es: "¿Tendrá un objeto de instancia que contenga todas las propiedades de la clase Parent", la respuesta es
''Sí'', tendrá todas las propiedades y campos que haya copiado en la clase principal en la instancia secundaria.
No, no lo hace, pero llama al constructor base (el constructor de la clase padre). Lo que en su caso está vacío, por lo que el compilador realiza la llamada al constructor de la clase base:
class Program
{
public class ParentClass
{
public ParentClass()
{
Console.WriteLine("ChildClass drived from me ");
}
}
public class ChildClass : ParentClass
{
public ChildClass() : base() // base() call is voluntary
{
Console.WriteLine("This also use my Ctor");
}
}
public static void Main()
{
ChildClass child = new ChildClass();
}
}
Sin embargo, si su clase base no tuviera un constructor sin parámetros, tendría que llamarlo
class Program
{
public class ParentClass
{
public ParentClass(string foo)
{
Console.WriteLine("ChildClass drived from me ");
}
}
public class ChildClass : ParentClass
{
public ChildClass() : base("some foo") // base call is obligatory
{
Console.WriteLine("This also use my Ctor");
}
}
public static void Main()
{
ChildClass child = new ChildClass();
}
}
Por definición, cuando ChildClass
hereda el formulario ParentClass
, los objetos ChildClass
pertenecen a ParentClass
.
Si su nombre estuviera más orientado a la vida real, sería más fácil de entender.
class Animal {}
class Cat : Animal {}
var rocky = new Cat();
Mira, Rocky es un gato, pero también es un animal.
No, solo creará una instancia de la clase secundaria.
Otra forma de pensar en una clase es como una plantilla para objetos. es decir, las instancias de objetos creadas a partir de esta clase deberían tener esta lógica de implementación. Al crear una instancia de una clase, toma toda esa lógica y la convierte en comportamiento para el objeto. Cuando hereda de alguna clase, básicamente está incluyendo la lógica de implementación de la clase principal en la plantilla de la clase secundaria, por lo que solo obtiene una "plantilla" extendida. Cuando crea una instancia de objeto a partir de esta plantilla, la instancia utiliza la plantilla secundaria, que contiene una combinación de la lógica definida en las clases primarias y secundarias.
Creación de instancias normales: lógica de clase -> plantilla -> instancia
Herencia: lógica de clase padre + lógica de clase hijo -> plantilla -> instancia