Tout d'abord, une clarification de la terminologie : nous attribuons une Child
à une variable de type Parent
. Parent
est une référence à un objet qui se trouve être un sous-type de Parent
, a Child
.
Elle n'est utile que dans un exemple plus compliqué. Imaginez que vous ajoutez getEmployeeDetails
à la classe Parent :
public String getEmployeeDetails() {
return "Name: " + name;
}
Nous pourrions surcharger cette méthode dans Child
pour fournir plus de détails :
@Override
public String getEmployeeDetails() {
return "Name: " + name + " Salary: " + salary;
}
Maintenant, vous pouvez écrire une ligne de code qui obtient tous les détails disponibles, que l'objet soit une Parent
o Child
:
parent.getEmployeeDetails();
Le code suivant :
Parent parent = new Parent();
parent.name = 1;
Child child = new Child();
child.name = 2;
child.salary = 2000;
Parent[] employees = new Parent[] { parent, child };
for (Parent employee : employees) {
employee.getEmployeeDetails();
}
Le résultat sera la sortie :
Name: 1
Name: 2 Salary: 2000
Nous avons utilisé un Child
en tant que Parent
. Il avait un comportement spécialisé propre à la Child
mais lorsque nous avons appelé getEmployeeDetails()
nous pourrions ignorer la différence et nous concentrer sur la façon dont Parent
y Child
sont similaires. C'est ce qu'on appelle polymorphisme de sous-type .
Votre question actualisée demande pourquoi Child.salary
n'est pas accessible lorsque le Child
est stocké dans un Parent
référence. La réponse est l'intersection du "polymorphisme" et du "typage statique". Parce que Java est typée statiquement au moment de la compilation, vous obtenez certaines garanties du compilateur, mais vous êtes obligé de suivre des règles en échange, sinon le code ne sera pas compilé. Ici, la garantie pertinente est que chaque instance d'un sous-type (par ex. Child
) peut être utilisé comme une instance de son supertype (par ex. Parent
). Par exemple, vous avez la garantie que lorsque vous accédez à employee.getEmployeeDetails
o employee.name
la méthode ou le champ est défini sur tout objet non nul qui pourrait être affecté à une variable employee
de type Parent
. Pour faire cette garantie, le compilateur ne considère que le type statique (en gros, le type de la référence de la variable, Parent
) pour décider de ce à quoi vous pouvez accéder. Vous ne pouvez donc pas accéder aux membres qui sont définis sur le type d'exécution de l'objet, Child
.
Lorsque vous voulez vraiment utiliser un Child
en tant que Parent
Il s'agit d'une restriction facile à accepter et votre code sera utilisable pour les applications suivantes Parent
et tous ses sous-types. Lorsque cela n'est pas acceptable, faites en sorte que le type de la référence Child
.