web-dev-qa-db-fra.com

Pourquoi le constructeur de la super classe est-il appelé lorsque nous déclarons l'objet de la sous-classe? (Java)

Considérons ce code:

class Test {
    Test() {
        System.out.println("In constructor of Superclass");
    }

    int adds(int n1, int n2) {
        return(n1+n2);
    }

    void print(int sum) {
        System.out.println("the sums are " + sum);
    }
}


class Test1 extends Test {
    Test1(int n1, int n2) {
        System.out.println("In constructor of Subclass");
        int sum = this.adds(n1,n2);
        this.print(sum);
    }

    public static void main(String[] args) {
        Test1 a=new Test1(13,12);
        Test c=new Test1(15,14);
    }
}

Si nous avons un constructeur en super classe, il sera invoqué par chaque objet que nous construirons pour la classe enfant (par exemple, Object a pour la classe Test1 appelle Test1(int n1, int n2) et ainsi que son parent Test()). 

Pourquoi cela arrive-t-il?

Le résultat de ce programme est:

En constructeur de Superclass

En constructeur de sous-classe

les sommes sont 25

En constructeur de Superclass

En constructeur de sous-classe

les sommes sont 29

32
aman_novice

Parce qu'il garantira que lorsqu'un constructeur est appelé, il peut compter sur tous les champs de sa super-classe en cours d'initialisation.

voir 3.4.4 dans ici

35
Ashkan Aryan

Oui. Une super-classe doit être construite avant de pouvoir construire une classe dérivée, sinon, certains champs qui devraient être disponibles dans la classe dérivée pourraient ne pas être initialisés.

Une petite note: Si vous devez appeler explicitement le constructeur de la super classe et lui transmettre quelques paramètres:

baseClassConstructor(){
    super(someParams);
}

alors le super constructeur doit être le premier appel de méthode au constructeur dérivé. Par exemple, cela ne compilera pas:

baseClassConstructor(){
     foo(); 
     super(someParams); // compilation error
}
18
Heisenbug

super () est ajouté automatiquement dans chaque constructeur de classe par le compilateur.

Comme nous le savons bien, le constructeur par défaut est automatiquement fourni par le compilateur, mais il ajoute également super () pour la première instruction. compiler fournira super () en tant que première déclaration du constructeur.

 enter image description here

8
Jaimin Patel

Les classes Java sont instanciées dans l'ordre suivant:

(au moment du chargement des classes) 0. initialiseurs pour les membres statiques et les blocs d’initialisation statiques, dans l’ordre de déclaration.

(à chaque nouvel objet) 

  1. créer des variables locales pour les arguments du constructeur
  2. si le constructeur commence par l'invocation d'un autre constructeur pour la classe , évaluez les arguments et effectuez une récurrence à l'étape précédente. Toutes les étapes Sont terminées pour ce constructeur, y compris la récurrence ultérieure des appels du constructeur Avant de continuer.
  3. si la superclasse n'a pas été construite par ce qui précède, construisez le la superclasse (en utilisant le constructeur no-arg si non spécifié). Comme # 2, Suivez toutes ces étapes pour la super-classe, y compris la construction de C’est la super-classe, avant de continuer.
  4. initialiseurs de variables d'instance et blocs d'initialisation non statiques, dans l'ordre de déclaration
  5. reste du constructeur.
3
Oh Chin Boon

C'est comme ça que Java fonctionne. Si vous créez un objet enfant, le super constructeur est appelé (implicitement).

2
anon

voici votre test d'extension à votre classe test1, ce qui signifie que vous pouvez accéder à toutes les méthodes et variables de test de votre test1. gardez à l'esprit que vous ne pouvez accéder à une méthode de classe ou à une variable que si de la mémoire lui est allouée et que, pour cela, il a besoin d'un constructeur défini par défaut ou paramétré. Par conséquent, lorsque le compilateur découvre qu'il étend une classe, il essa Super classe constructeur afin que vous pouvez accéder à toutes ses méthodes.

1
Akhil Vijayan

En termes simples, si la super-classe a un constructeur paramétré, vous devez appeler explicitement super (params) sur la première ligne de votre constructeur de classe enfant, sinon, tous les constructeurs de super-classe sont appelés implicitement.

1
Isham

"Si un constructeur n'appelle pas explicitement un constructeur de superclasse, le compilateur Java insère automatiquement un appel au constructeur sans argument de la superclasse. Si la super-classe n'a pas de constructeur sans argument, vous obtiendrez une erreur de compilation Object possède un tel constructeur, donc si Object est la seule superclasse, il n’ya pas de problème. "
(source: https://docs.Oracle.com/javase/tutorial/Java/IandI/super.html )

1
Sameer Khanal

Le constructeur de la classe de base sera appelé avant le constructeur de la classe dérivée. Cela a du sens car cela garantit que la classe de base est correctement construite lorsque le constructeur de la classe dérivée est exécuté. Cela vous permet d'utiliser certaines des données de la classe de base lors de la construction de la classe dérivée.

1
Ravi

Comme nous le savons, les variables membres (champs) d’une classe doivent être initialisées avant de créer un objet, car ces champs représentent l’état de l’objet. Si ces champs ne sont pas explicitement initiés, le compilateur leur fournit implicitement les valeurs par défaut en appelant le constructeur par défaut sans argument. C'est pourquoi le constructeur de la sous-classe appelle le constructeur par défaut de la super-classe ou est implicitement appelé par le compilateur. Les variables locales ne sont pas fournies par le compilateur.

1
maneeshp626

Lorsque nous créons un objet de sous-classe, il doit prendre en compte toutes les fonctions membres et les variables membres définies dans la superclasse. Dans certains cas, une variable membre pourrait être initialisée dans certains des constructeurs de la superclasse. Par conséquent, lorsque nous créons un objet de sous-classe, tous les constructeurs de l'arbre d'héritage correspondant sont appelés de la manière la plus descendante.

Plus précisément, lorsqu'une variable est définie comme protected elle sera toujours accessible dans la sous-classe, que la sous-classe soit dans le même package ou non . Maintenant, à partir de la sous-classe, si nous appelons une fonction de super-classe pour imprimer la valeur de cette variable protégée (qui peut être initialisée dans le constructeur de la super-classe), nous devons obtenir la valeur initialisée correcte. Par conséquent, tous les constructeurs de la super-classe sont appelés.

En interne, Java appelle super () dans chaque constructeur. Ainsi, chaque constructeur de sous-classe appelle son constructeur de super-classe à l'aide de super () et s'exécute donc de haut en bas.

Remarque: Les fonctions peuvent être remplacées, pas les variables. 

1
Aniket Thakur

Je vais essayer de répondre à cette question sous un angle différent. 

Supposons que Java n’appelle pas automatiquement le super constructeur. Si vous héritez de la classe, vous devrez soit appeler implicitement le super constructeur, soit le réécrire vous-même. Cela exigerait que vous ayez une connaissance interne du fonctionnement de la classe supérieure, ce qui est une mauvaise chose. Il faudrait également réécrire le code, ce qui n’est pas bon non plus. 

Je conviens que le fait d'appeler le super constructeur en coulisse est un peu peu intuitif. D'autre part, je ne sais pas comment ils auraient pu le faire de manière plus intuitive. 

1
NL3294

Il existe un appel super () par défaut dans vos constructeurs par défaut de sous-classes.

 //Default constructor of subClass
    subClass() {
    super();
    }
1
Bhaskar

La sous-classe hérite des champs de sa superclasse (s) et ces champs doivent être construits/initialisés (c'est le but habituel d'un constructeur: initier les membres de la classe pour que l'instance fonctionne correctement. Nous savons que certaines personnes mais beaucoup plus de fonctionnalités dans ces pauvres constructeurs ...)

1
Andreas_D

Dans la mesure où vous héritez des propriétés de classe de base dans une classe dérivée, il peut arriver que votre constructeur de classe dérivée demande à certaines variables de la classe de base d'initialiser ses variables. Donc, il faut d’abord initialiser les variables de classe de base, puis les variables de classe dérivées. C'est pourquoi Java appelle le premier constructeur de classe de base, puis le constructeur de classe dérivée.

Et aussi cela n’a aucun sens d’initialiser la classe enfant sans initialiser la classe parent.

1
user1923551

Constructor implémente une logique qui rend l'objet prêt à fonctionner. L'objet peut contenir l'état dans des champs privés, de sorte que seules les méthodes de sa classe peuvent y accéder. Donc, si vous souhaitez que l’instance de votre sous-classe soit vraiment prête à fonctionner après l’appel du constructeur (c’est-à-dire que toutes ses fonctionnalités, y compris celles héritées de la classe de base, sont OK), le constructeur de la classe de base doit être appelé. 

C'est pourquoi le système fonctionne de cette façon. 

Automatiquement, le constructeur par défaut de la classe de base est appelé. Si vous voulez changer cela, vous devez appeler explicitement le constructeur de la classe de base en écrivant super() dans la première ligne du constructeur de votre sous-classe.

1
AlexR

Le constructeur de la classe Super est appelé en premier parce que toutes les méthodes du programme sont d'abord présentées dans le tas et après la compilation, elles sont stockées dans la pile, ce qui explique pourquoi le constructeur de la super classe est appelé en premier.

1
Mukul Goyal

Les parents sortent les premiers! !! Et comme dans le monde réel, un enfant ne peut exister sans les parents .. Il est donc important d'initialiser les parents (SuperClass) avant de pouvoir les utiliser dans les classes d'enfants (sous-classe) ..

0
Shubham Soni