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
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
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
}
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.
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)
C'est comme ça que Java fonctionne. Si vous créez un objet enfant, le super constructeur est appelé (implicitement).
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.
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.
"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 )
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.
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.
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.
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.
Il existe un appel super () par défaut dans vos constructeurs par défaut de sous-classes.
//Default constructor of subClass
subClass() {
super();
}
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 ...)
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.
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.
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.
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) ..