57 votes

Combien d'objets sont créés grâce à l'héritage en java ?

Disons que j'ai trois classes :

class A {
    A() {
        // super(); 
        System.out.println("class A");
    }
}
class B extends A {
    B() {
        // super(); 
        System.out.println("class B");
    }
}
class C extends B {
    public static void main(String args[]) {
        C c = new C(); //Parent constructor will get called
    }
}

Lorsque je crée une instance de la classe C, elle appelle le constructeur de la super classe. Alors, y a-t-il plus d'un objet qui est créé ? Si un seul objet est créé, en quoi la méthode super() est-elle similaire au constructeur d'une autre classe ? La méthode super() crée-t-elle un objet en interne ? Ce que je sais, c'est que le constructeur est aussi une méthode (je peux me tromper).

Mes questions sont les suivantes :

  1. Combien d'objets sont créés dans ce cas ?
  2. Si un objet est créé, comment Super() appelle-t-il en interne le constructeur de la classe parent ?

64voto

Andrew Alcock Points 10536

Grande question. Ce que vous voulez savoir, c'est comment Java initialiser les objets - et il y a un certain nombre d'étapes à franchir.

Je sais que le constructeur est aussi une méthode (je me trompe peut-être).

Presque à droite. Le Constructeur est une méthode spéciale. Si vous décompilez un fichier de classe, vous verrez que les constructeurs sont renommés en <init> . <init> est traitée différemment des autres méthodes et, par exemple, ne peut pas être appelée explicitement sauf par l'utilisation du mot-clé new ou super . Cette fonction est si fondamentale qu'elle est mise en œuvre dans la JVM elle-même plutôt que d'être définie dans le langage Java.

Combien de nombre d'objets sont créés dans ce cas.

Un objet est créé - une instance de C .

C est en outre et simultanément une instance de B et une instance de A et aussi Object .

Si un objet est créé alors comment en interne super() appelle le constructeur de la classe Parent . Comment Super est capable d'appeler le constructeur de la classe parent.

C'est là que nous entrons dans l'initialisation - l'initialisation est la façon dont la JVM crée une nouvelle instance d'un objet et définit toutes les valeurs des membres - celles de la classe spécifique et celles des superclasses. Plusieurs étapes sont nécessaires :

  • Charger toutes les classes référencées et initialiser ces classes. L'initialisation des classes n'est pas triviale en soi, je ne l'aborderai donc pas ici. Elle vaut la peine d'être lue.

  • Allouer un morceau de mémoire pour contenir les membres de l'instance, qui inclura tous les membres de l'instance. A , B et C . NOTE cela explique un aspect de votre question : comment les constructeurs de la classe de base et de ses sous-classes peuvent-ils mettre à jour ou faire référence au même objet ? tous les membres de l'instance de toutes les classes sont stockés les uns après les autres dans le même morceau de mémoire. .

  • Initialiser tous les membres à leur valeur par défaut . Par exemple, int et float seront fixés à 0 et 0.0f.

  • Exécuter ou calculer les initialisateurs des membres, par exemple :

    private int a = 10;
    private int b = a * 5;
    private String c = Singleton.getInstance().getValue();
  • Notez (1) que l'initialisation des membres se produit strictement dans l'ordre où les membres sont déclarés dans la classe. Cela signifie que les références aux membres plus tard dans la déclaration sont brisées :

    private int a = b * 5; // Forward reference; won't compile
    private int b = 10;
  • Notez (2) qu'il existe en Java une fonction sous-utilisée permettant d'exécuter un code arbitraire pour initialiser des valeurs. avant le constructeur est exécuté. Ces blocs de code sont exécutés à ce moment-là à nouveau strictement dans l'ordre de déclaration :

    private int a;
    private int b = 1;
    {
        // Initization occurs after b but before c.
        // c cannot be referenced here at all
        int i = SomeClass.getSomeStatic();
        a = i * 2;
    }
    private int c = 99;
  • Exécutez le constructeur de C . Les constructeurs doivent soit invoquer directement un constructeur de la superclasse, soit le compilateur ajoutera automatiquement l'option super() comme première ligne du constructeur. Cela signifie que les constructeurs sont strictement exécutés dans l'ordre :

    1. Object
    2. A
    3. B
    4. C

L'objet est maintenant initialisé et est prêt à être utilisé. Vous pouvez faire des choses dangereuses si vous initialisez une valeur en utilisant des méthodes d'instance :

public class Wrong {
    int a = getB(); // Don't do this!
    int b = 10;
    public int getB() {
         return b;
    }
}

Ici, a est initialisé à 0 . En effet, au moment où getB() est invoquée, Java a effacé la valeur de l'élément b à la valeur par défaut ( 0 ), mais ne l'a pas encore réglé sur 10 dans la deuxième phase d'initialisation.

En résumé, il n'y a qu'un seul objet et il est créé et initialisé en plusieurs étapes. Pendant ces étapes, l'objet n'est, par définition, pas complètement défini.

8voto

pankaj Points 153
  1. Il y aura un et un seul objet créé, c'est-à-dire un objet A.

  2. Vous pouvez imaginer que lorsque la classe A étend B, alors toutes les méthodes et variables sont copiées dans la classe A.

6voto

Gaurav_Java Points 183

Dans le code, un seul objet sera créé et le super appelle le constructeur de la classe parent.

Preuve de la création de l'objet :

package one;

public class A {
    public static A super_var;

    public A() {
        super_var = this;
        System.out.println("Constrcutor of A invoked");
    }
}

package two;

public class B extends A {
    public static A sub_var;

    public B() {
        sub_var = this;
        System.out.println("Constructor of B invoked");
    }

    public void confirm() {
        if (sub_var == A.super_var)
            System.out.println("There is only one object is created");
        else
            System.out.println("There are more than one object created");
    }

    public static void main(String Args[]) {
        B x = new B();
        x.confirm();
    }
}

Cela prouvera qu'il n'y aura qu'un seul objet créé.

Et sur Super() . Ce que je sais, c'est qu'il appelle le constructeur de la classe Parent. et que chaque constructeur a Super() comme première déclaration comme vous le mentionnez dans votre code . afin que vous sachiez

Je ne sais pas comment il appelle en interne le constructeur de la super classe.

J'espère que cela vous fera comprendre qu'il n'y a que l'espace que vous créez dans le programme.

2voto

sanbhat Points 11558

Vos classes seront converties en interne en quelque chose comme ceci

class A
{
    A(){
        super(); 
        System.out.println("class A");
    }
}

class B extends A{
    B(){
        super(); 
        System.out.println("class B");
    }
}

public class C extends B
{
    public static void main(String args[])
    {
        C c  = new C(); //Parent constructor will get call 
    }
}

Combien de nombre d'objets sont créés dans ce cas.

Un seul, qui est une instance de C en appelant super() juste invoque le site Constructeur de classe parentale et ne crée pas d'objet

Si un objet est créé, comment faire pour que Super() appelle Parent en interne ? classe Constructeur . Comment Super est capable d'appeler la classe parent parent.

Lorsque vous créez C de l'instance. C est appelé, qui appelle tout d'abord B qui, à son tour, appelle le constructeur de A du constructeur

1voto

Backtrack Points 2371

Le mot clé super permet à une sous-classe d'appeler les méthodes et les champs de sa superclasse. Il ne s'agit pas d'une instance de l'objet de la superclasse. mais un moyen d'indiquer au compilateur les méthodes ou les champs à référencer. L'effet est le même que si la sous-classe appelait une de ses propres méthodes. Exemples :

Considérons une sous-classe Employé qui étend sa super-classe Personne :

public class Employee extends Person{

   public Employee()
   {
     //reference the superclass constructor 
     super(); 
   }

   public String getName()
   {
     //reference superclass behaviors
     return super.getFirstName() + " " + super.getLastName();
   }
 } 

Le mot-clé super peut être utilisé pour faire référence au constructeur de la classe Personne ou à tout comportement ou champ auquel il a accès (par exemple, getFirstName() et getLastName()).

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X