web-dev-qa-db-fra.com

La création d'une instance d'une classe enfant crée-t-elle une instance de la classe parent?

Je connais C # et je voulais savoir que si je crée une instance d'une classe enfant, une instance de la classe parent est-elle automatiquement créée ou quoi?

Voici mon code:

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();
    }
}
26
brk

crée-t-il aussi automatiquement une instance de la classe Parent?

Pas une instance séparée; ChildClassis une instance ParentClass, lorsqu'il est question d'héritage.

En mots, cela ressemble à:

lors de la création d'un chien, crée-t-on également une instance d'un animal?

Nous ne créons pas un chien et (séparément) ne créons pas un animal; le chien est l'instance animal. Et si nous créons un caniche, le caniche est le chien et est l'animal.

63
Marc Gravell

Non, mais appelle le constructeur de base (le constructeur de la classe parente). Ce qui dans votre cas est vide, donc l'appel au constructeur de la classe de base est fait pour vous par le compilateur:

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();
    }
}

Cependant, si votre classe de base n’avait pas de constructeur sans paramètre, vous devriez l’appeler

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();
    }
}

Par définition, lorsque ChildClass hérite de la forme ParentClass, les objets ChildClass appartiennent également à ParentClass.

Si votre nom était davantage axé sur la vie réelle, il serait plus facile à comprendre.

class Animal {}
class Cat : Animal {}

var rocky = new Cat();

Rocky est un chat, mais est un animal aussi.

9
Andrzej Gis

La réponse réelle à votre question est 

'Non', c'est une instance de la classe Child, pas du parent.

Mais si votre question est: "aurez-vous un objet d'instance contenant toutes les propriétés de la classe parent", la réponse est 

'Oui', vous aurez toutes les propriétés et tous les champs que vous avez dans le fichier Classe parent copiée dans l'instance Child.

8
Mayer Spitzer

En parlant spécifiquement de votre code:

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();


    }
}

J'ai changé les messages pour les rendre pertinents par rapport au point soulevé:

Un constructeur est simplement une méthode appelée par la force chaque fois qu'un nouvel objet est créé. Vous l'utilisez pour définir le nouvel objet à utiliser, initialiser les propriétés, etc. Les classes sont hiérarchiques en C # - tout est toujours une sous-classe de quelque chose, parfois Object. Votre parentClass est un enfant de Object, il ne dit simplement pas. Votre enfant est déclaré enfant de parent

Comme d'autres l'ont noté, vous n'obtenez pas plusieurs instances d'objets lorsque vous utilisez new, vous obtenez une instance de ce que vous avez demandé de créer. Les classes enfants peuvent toujours être référencées/"stockées dans" une variable déclarée être un type parent. C'est parce que les choses ont une relation "est-une" dans la direction de Child -> Parent. Un chien est un animal, un chat est un animal, un animal est un objet. Ils n'ont pas de relation dans la direction opposée. Vous ne pouvez pas universellement dire qu'une voiture est une Ferrari, ou qu'un animal est un chien. 

Ainsi, les choses remontent dans la hiérarchie et vous pouvez stocker un chat ou un chien à l'intérieur d'une variable déclarée contenir un animal. Animal peut avoir une méthode GetNumberOfLegs (), qui indique le nombre de pattes. Chat et Chien reviendraient chacun 4, Monkey reviendrait 2. 

L'un des principes clés de la programmation orientée objet est que vous pouvez vous référer à des choses de manière générique. tous les animaux ont un certain nombre de pattes. Si c'est un chat/chien stocké dans l'Animal, alors GetNumberOfLegs () renvoie 4, si c'est un singe, il retourne 2. Mais vous n'avez pas besoin de savoir précisément qu'il s'agit d'un chat, d'un chien ou d'un singe si tout ce qui vous intéresse est le nombre de jambes. Cela sera traité plus en détail dans les conférences à venir, je n'ai donc pas besoin de trop m'étendre ici. Je mets ce détail pour expliquer pourquoi nous pourrions même avoir une hiérarchie, un animal, créer un chien et le stocker dans une variable de type animal. Nous le faisons parce que nous voulons souvent faire référence à des choses de manière générique parce que nous ne nous soucions pas des détails; nous définissons les choses génériques qui nous intéressent, et des choses spécifiques s’inscrivent dans le moule. Vous pouvez conduire une voiture; vous n'avez pas besoin d'apprendre spécifiquement à conduire une Ford ou une Chevrolet - ils ont le volant et les pédales au même endroit/agencement. Vous pouvez utiliser l'interface générique. Vous ne vous souciez pas de la façon dont la direction est mise en œuvre - hydraulique, à pignon et crémaillère, bras Pitman - vous vous souciez simplement que lorsque vous tournez le volant "comme ça", la voiture aille "comme ça". 

Revenons à ce que vous avez demandé:

Parce que Child est un parent est un objet, lorsque vous créez un nouvel enfant, une impression indique que le constructeur parent a été appelé et une autre indique que le constructeur enfant a été appelé. Cela n'indique pas que 2 objets ont été créés dans la mémoire de l'ordinateur. Les constructeurs sont appelés dans l'ordre suivant (de bas en haut) pour tout dans la hiérarchie, en commençant par Object, puis Parent, puis Child. C'est ainsi que la première chose dans le code d'un constructeur est un appel à un constructeur parent pertinent. La première chose dans le code de ce constructeur est un appel à son parent

Le runtime commence donc à l'enfant, puis va au parent, le grand-parent, l'arrière-grand-parent, jusqu'au sommet de l'ascendance, puis redescend, en exécutant le reste du code dans chaque constructeur dans l'ordre, de haut en bas. . C’est pourquoi vous voyez l’impression que le constructeur Parent a été appelée, puis vous voyez l’enfant

C'est tout un et le même objet, c'est plusieurs appels de méthode. Voir deux impressions ne signifie pas qu'il y a deux objets en mémoire, c'est un objet avec deux méthodes (deux méthodes de constructeur) qui ont été appelées dans un ordre récursif.

3
Caius Jard

Une autre façon de penser à une classe est simplement un modèle pour les objets. Les instances d'objet créées à partir de cette classe doivent avoir cette logique d'implémentation. La création d'une instance d'une classe prend toute cette logique et la convertit en comportement pour l'objet. Lorsque vous héritez d'une classe, vous incluez essentiellement la logique d'implémentation de la classe parente dans le modèle de la classe enfant. Vous obtenez donc simplement un "modèle" étendu. Lorsque vous créez une instance d'objet à partir de ce modèle, celle-ci utilise le modèle enfant, qui contient une combinaison de la logique définie dans les classes parent et enfant.

Instanciation normale: Logique de classe -> template -> instance

Héritage: Logique de classe parent + logique de classe enfant -> template -> instance 

2
Jamiel Thomas

supposons que vous ayez la classe parent Coffee et la classe enfant Cappucino

class Coffee {}

class Cappucino : Coffee {}

en émettant new Cappucino(), une instance est créée pour Cappucino. Cappucino est en réalité du café et les propriétés du café sont héritées de Cappucino. 

Aucune instance séparée n'est créée pour Coffee.

Cappucino porte les caractéristiques du café par héritage

1
Simonare

Non, cela ne fera que créer une instance de la classe enfant.

1
Sr.Mento