web-dev-qa-db-fra.com

Pourquoi les constructeurs ne peuvent pas être hérités en Java?

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++

34
Mayank Tiwari

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

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:

  1. new - alloue de la mémoire pour l'objet
  2. invokespecial - appelle le constructeur sur la mémoire allouée récemment

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:

  1. Les constructeurs ne sont pas hérités au niveau de la langue en raison des principes OO
  2. Les constructeurs sont hérités au niveau du bytecode
15
Mikhail

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

12
Suresh Atta
  • Un constructeur ne peut être appelé qu'avec new. Il ne peut pas être appelé comme une méthode.
  • Le nom du constructeur est identique au nom de la classe.

Donc, l'héritage n'est pratiquement pas possible en tant que tel . Cependant, dans une construction, on pourrait appeler d'autres constructeurs.

  • Dans la même classe, en utilisant this(...);
  • De la classe étendue utilisant 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.

2
Joop Eggen

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.

1
Nikhil

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.

1
Rahul Tripathi

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.

1
user6521421

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.

0
KGhatak

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);
    }
}
0
J.d. Patel

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

0
Ashwini E