Pourquoi ne peut-on pas hériter du constructeur ?

VonDriguen
Pourquoi ne peut-on pas hériter du constructeur ?

Bonjour,

Ma question réside dans le titre : "Pourquoi les développeurs de Java n'ont-ils pas permis qu'une classe fille hérite du constructeur de la classe mère ?"

Je sais déjà que l'on peut utiliser le type super pour avoir accès aux valeurs de la classe mère mais là n'est pas la question !!! Je veux juste savoir ce qui a poussé les développeurs de Java à empêcher une classe fille d'hériter du constructeur de la classe mère. Pourquoi une telle décision ?

D'avance merci :D

nasix
Re: Pourquoi ne peut-on pas hériter du constructeur ?

Bonjour,

Déjà si je comprends bien, tu veux dire, pourquoi on ne peut pas hériter le (et non pas du) constructeur ? Si c'est ça la question alors je te fais une analyse.

L'héritage est le fait qu'une classe reproduit le même comportement (pour les méthodes) et acquiert les même propriété (attributs) de sa classe mère.

Si on veut que les classes filles d'une classe A aient les même comportements f(), g() et h(). Il suffira alors de mettre ces méthodes visibles et non final et d'hériter de cette classe.

Pour les constructeurs, les choses sont différentes, le constructeur n'est pas une méthode, c'est la procédure de construction de l'objet, si tu en as plusieurs, alors tu as plusieurs façons de construire un objet. l'appel du constructeur est obligatoire avant l'utilisation de l'objet. D'où la première différence.

L'héritage est aussi une utilisation, une classe B héritant de A produit des objets de type B, et chaque objet de type B est un objet A plus les comportements (et propriétés) propre à B (non hérités de A). Ceci dit, pour construire un objet B, il faut avoir un objet A, auquel on rajoutera ce qui est spécifique à B, et donc la toute première étape pour la création d'un objet B est la création d'un objet A, et c'est exactement ce que fait le constructeur de B. On dit que les constructeurs de B appellent, avant tout, (implicitement ou explicitement) un constructeur de A. Donc la classe B appelle forcément un des constructeurs de A, on peut choisir lequel B appellera-t-elle ? mais pas si on appelle ou non le constructeur parent.

Une dernière chose, tu ne peux jamais appeler un constructeur via (this() ou super()) en dehors des constructeurs (en dehors de la phase de construction), parce que la construction de l'objet se fait une seul fois, et une fois tu as un objet, tu ne peux pas le recréer, tu peux créer un autre, mais pas le même. Tu peux donc appeler les fonction f, g et h tant de fois que tu en veux, mais tu ne peux pas appeler les constructeurs plus qu'une fois pour le même objet, voilà pourquoi les constructeurs sont différents. Et voilà pourquoi elle sont utilisés dans les classes filles et non pas hérités.

Il se peut bien que je m'exprime mal, s'il y a un point que j'ai mal expliqué, tu peux me faire signe.
Bonne chance.

VonDriguen
Re: Pourquoi ne peut-on pas hériter du constructeur ?

Merci nasix de te pencher sur la question.

Je comprends bien ce que tu dis mais je voudrais pousser la réflexion encore plus loin. Imaginons qu'on a un constructeur surchargé 5 fois :

class A  
 {  
     A(){}  
     A(int i) {}  
     A(String s) {}  
     A(int i, int j) {}  
     A(String s, int i) {}  
 }  

Et que je crée une class B qui hérite de A :
class B extends A {}
Je vais devoir recréer chacun des constructeurs à l'aide du mot-clef super.
Pourquoi les développeurs de Java n'ont pas décidé que, dès que les constructeurs de la classe A sont créés, le compilateur soit assez intelligent pour faire appel à l'un deux lors de la création de B. Cela nous déchargerait de devoir recréer chacun des constructeurs de la classe parent.
Je suis d'accord qu'il faudrait peut-être créer un mot clef pour dire à quelle surcharge l'on veut faire appel !

Je sais que dans d'autres langages (le Delphi par exemple et si ma mémoire ne me trompe pas), que le constructeur est hérité, et nous permet donc un gain de temps considérable lorsque l'on hérite d'une classe qui elle même est déjà héritée d'une autre qui elle-même, etc.

Ma question devient peut-être philosophique et si ça compte, seul les développeurs de java connaissent la réponse... mais je ne perds pas espoir que quelqu'un puisse me répondre :-)

nasix
Re: Pourquoi ne peut-on pas hériter du constructeur ?

Ce n'est jamais grave, j'aime la philosophie objet, je te jure. Et des fois je prends mon café et je me pose des questions assez bizarres ? tu peux prendre mon contact privé et on mène des discussions à chaque fois que tu le souhaite.

Bon, pour ta question, si je comprends bien, tu veux dire, pourquoi le constructeur d'une classe fille B n'appelle-t-il pas automatiquement un constructeur de sa classe mère A, sans faire intervenir le développeur ? si c'est bien ça ta question, alors j'affirme que chaque constructeur appelle un constructeur de sa classe mère, sauf les constructeurs de la classe Object pour la simple raison que cette dernière n'a pas de classe mère.

Si tu précise quel constructeur de la classe mère appeler, via super(), super(i), super("chaine") alors OK. Sinon le constructeur de la classe fille appelle automatiquement et obligatoirement le constructeur sans argument de la classe mère. Dans ce cas tu as deux situations, la première est celle où tu as bien un constructeur sans argument dans la classe mère, auquel cas il sera appelé et la deuxième où tu n'as pas ce constructeur, auquel cas tu as une erreur de compilation parce que tu appelle implicitement un constructeur qui n'existe pas.

Donc il est à retenir que le constructeur appelé implicitement est celui par défaut (sans argument), voici donc des exemples concrets dans ce sens.

Exemple 1:
public class A {}

est équivalente à :

public class A {
	public A() {
	}
}

et est équivalente aussi à :

public class A {
	public A() {
		super();
	}
}

Exemple 2:

public class A {
	public A(int i) {
	}
}

est équivalente à :

public class A {
	public A(int i) {
                super();
	}
}

Si on considère maintenant :

class B extends A{
}

B est équivalente à :

class B extends A{
	B(){
	}
}

et aussi à :

class B extends A{
	B(){
            super();
	}
}

Par contre le constructeur super() sans arguments n'existe pas dans A, raison pour laquelle B présente une erreur de compilation, la seule façon pour résoudre ce problème est :

class B extends A{
	B(){
		super(1);  // Le 1 est juste un exemple d'entier
	}
}

Voilà, j'espère que je me suis bien expliqué, et que c'est plus clair maintenant, sinon, j'attends tes observations.