J'ai les 2 cours suivants
public class classA {
classA() {
System.out.println("A");
}
}
class classB extends classA {
classB() {
System.out.println("B");
}
}
puis en cours d'exécution
classA c = new classB();
ou
classB c = new classB();
donne toujours
A
B
Pourquoi cela arrive-t-il? À première vue, dans l'un ou l'autre scénario, je suppose que seul le constructeur classB
serait appelé et que la seule sortie serait
B
mais c'est clairement faux.
C'est ainsi que fonctionne Java. Les constructeurs des classes parentes sont appelés, tout en haut de la hiérarchie des classes via Object
, avant l'appel du constructeur de la classe enfant.
Citant de les docs :
Avec
super()
, le constructeur sans argument de la superclasse est appelé. Avecsuper(parameter list)
, le constructeur de superclasse avec une liste de paramètres correspondante est appelé.Remarque: Si un constructeur n'invoque pas explicitement un constructeur de superclasse, le 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 au moment de la compilation.
Object
a un tel constructeur, donc siObject
est la seule superclasse, il n'y a pas de problème.Si un constructeur de sous-classe invoque un constructeur de sa superclasse, explicitement ou implicitement, vous pourriez penser qu'il y aura toute une chaîne de constructeurs appelée, tout le chemin du constructeur de
Object
. En fait, c'est le cas. Il s'appelle chaînage constructeur, et vous devez en être conscient quand il y a une longue lignée de descente de classe.
Le constructeur de super classe est toujours appelé pendant le processus de construction et il est garanti que la construction de super classe est terminée avant l'appel du constructeur de sous-classe. C'est le cas pour la plupart sinon la totalité du langage orienté objet. Vous pouvez explicitement appeler le constructeur de super classe avec paramètre si vous ne voulez pas invoquer le constructeur par défaut; sinon, cet appel est automatisé par le compilateur.
Il n'y a pas de différence dans les deux déclarations en termes d'objets en construction, vous voyez donc la même chose.
L'utilisation d'un type de référence différent sur le côté gauche lors de la construction des mêmes objets à l'aide de new
ne fera aucune différence en ce qui concerne la création d'objets et le chaînage des constructeurs.
Quelle que soit la différence entre deux de vos instructions, c'est après la création des objets.