Je suis un débutant en langage de programmation Java, j'ai récemment appris que constructeurs ne peuvent pas être hérités en Java. Quelqu'un peut-il expliquer pourquoi?
J'ai déjà lu ce lien de C++
En termes simples, un constructeur ne peut pas être hérité, car il a un nom différent dans les sous-classes (le nom de la sous-classe).
class A {
A();
}
class B extends A{
B();
}
Vous ne pouvez faire que:
B b = new B(); // and not new A()
Les méthodes, à la place, sont héritées avec "le même nom" et peuvent être utilisées.
En ce qui concerne la raison: Il n’aurait pas beaucoup de sens à hériter d’un constructeur, car constructeur de classe A signifie créer un objet de type A, et constructeur de classe B signifie créer un objet de classe B.
Vous pouvez toujours utiliser constructeurs à partir de l'implémentation de B dans B:
class B extends A{
B() { super(); }
}
Vous parlez de niveau de langage Java. Si les constructeurs étaient hérités, cela rendrait impossible la classe privée. Comme nous le savons, la visibilité de la méthode ne peut pas être dégradée. Object
class a un constructeur sans argument et chaque classe étend Object
, donc en cas d'héritage de constructeur chaque classe aurait un constructeur sans argument. Cela enfreint les OO principes.
Les choses sont différentes au niveau du bytecode. Lors de la création de l'objet, deux opérateurs sont appelés:
Nous pouvons modifier le bytecode pour que la mémoire soit allouée à la classe Child et que le constructeur soit appelé à partir de la classe Parent. Dans ce cas, nous pouvons dire que les constructeurs sont hérités. Si vous ne désactivez pas la vérification du code octet, JVM lève une exception lors du chargement de la classe. Nous pouvons le faire en ajoutant l'argument -noverify
.
Conclusion:
Raison mentionnée dans la documentation de l'héritage
Une sous-classe hérite de tous les membres (champs, méthodes et classes imbriquées) de sa superclasse. Les constructeurs ne sont pas membres et ne sont donc pas hérités par les sous-classes, mais le constructeur de la superclasse peut être appelé à partir de la sous-classe.
Vous pouvez vous référer à la documentation de Fournir des constructeurs pour vos classes
new
. Il ne peut pas être appelé comme une méthode.Donc, l'héritage n'est pratiquement pas possible en tant que tel . Cependant, dans une construction, on pourrait appeler d'autres constructeurs.
this(...)
;super(...)
;Exemple
class A {
A() { } // Constructor
A(int a) { } // Constructor
A(boolean c) { } // Constructor
}
class B extends A {
B() {
this(3, 7);
}
B(int a) {
super();
}
B(String b) {
super(7);
}
B(int a, int c) { // Calls super() implicitly
}
}
A a = new B(8):
Il n'y a malheureusement aucune possibilité d'utiliser le constructeur de A pour un booléen:
B b = new B(true): // ERROR
Les langages conçus auraient pu implémenter une chose comme:
Générer pour chaque constructeur public de la classe de base, un constructeur avec la même signature si un tel constructeur n'est pas déjà défini. Appelez super
avec les mêmes paramètres. Appelez this()
s'il existe un constructeur par défaut.
Cela semble un peu gonfler le code. Et ce n’est pas simplement un pointeur dans une table de méthode virtuelle, grâce à laquelle l’héritage/le remplacement de méthodes fonctionne.
Réponse simple, j’ai observé: vous ne pouvez pas invoquer ou utiliser directement les constructeurs de la classe parent dans la classe enfant, mais les méthodes de la classe parent que vous pouvez utiliser directement dans la classe enfant.
Dans le cas où vous avez une méthode dans la classe enfant avec le même nom que dans la classe parent à ce moment-là, vous devez uniquement utiliser le mot clé "super" pour appeler la méthode de la classe parent afin de résoudre l'ambiguïté des appels.
"Pour appeler" le constructeur de la classe parent dans la classe enfant, vous avez toujours besoin du mot clé "super". Ainsi, les constructeurs de la classe parent ne sont "pas directement disponibles" comme les méthodes de la classe parent dans la classe enfant. Nous pouvons donc dire que les constructeurs ne peuvent pas être hérités.
Les constructeurs ne sont pas membres de classes et seuls les membres sont hérités. Vous ne pouvez pas hériter d'un constructeur. Autrement dit, vous ne pouvez pas créer une instance d'une sous-classe à l'aide du constructeur de l'une de ses superclasses.
Seuls les champs, les méthodes et les classes imbriquées sont membres de toutes les classes autres que les constructeurs. Une sous-classe hérite de tous les membres tels que (champs, méthodes et classes imbriquées) de sa superclasse. Les constructeurs ne sont pas membres et ne sont donc pas hérités par les sous-classes, mais le constructeur de la superclasse peut être appelé à partir de la sous-classe.
Les limitations syntaxiques peuvent souvent être contournées s’il existe une raison quelconque pour une fonctionnalité de manière conceptuelle. Avec cela, je pense, la vraie raison de ne pas supporter l'héritage du constructeur n'est pas due à des limitations syntaxiques mais plutôt à une sémantique.
Conceptuellement, l'héritage fournit un mécanisme pour acquérir (ou hériter) d'un comportement et très probablement sans écrire de code, car son but est de fournir du code réutilisé. Pour une classe enfant, il ne faut en aucun cas hériter du comportement d'initialisation de sa classe parente. Après tout, un comportement hérité trouve son meilleur usage lorsqu'un appelant externe peut l'utiliser sans savoir qui (dans la chaîne parente) l'a réellement implémenté. Comme vous pouvez le constater, un appelant n’a pratiquement aucune raison de savoir comment une classe parent est initialisée via sa classe enfant. Il n’existe aucune raison discernable de prendre en charge l’héritage pour le constructeur d’une classe parent.
vous ne pouvez pas hériter des constructeurs, mais vous pouvez hériter de la valeur initialisée dans le constructeur comme
class test1 {
int a,b;
test1(){
a = 100;
b = 20;
}
}
class test2 extends test1 {
test2(){
// do something
}
}
class test {
public static void main(String[] args) {
test2 t = new test2();
int a = t.a;
int b = t.b;
System.out.println(a+b);
}
}
Non, les constructeurs ne seront pas hérités dans la sous-classe, même si c'est un membre non statique, ils ne seront pas hérités dans la sous-classe car les constructeurs ne seront pas chargés à l'intérieur de l'objet. Les constructeurs sont comme un initialiseur non statique