Zunächst eine Klarstellung der Terminologie: Wir weisen Childeiner Variablen vom Typ ein Objekt zu Parent. Parentist eine Referenz auf ein Objekt, das zufällig ein Subtyp von Parenta ist Child.
Es ist nur in einem komplizierteren Beispiel nützlich. Stellen Sie sich vor, Sie fügen getEmployeeDetailsder Klasse Parent Folgendes hinzu:
public String getEmployeeDetails() {
return "Name: " + name;
}
Wir könnten diese Methode überschreiben, Childum weitere Details bereitzustellen:
@Override
public String getEmployeeDetails() {
return "Name: " + name + " Salary: " + salary;
}
Jetzt können Sie eine Codezeile schreiben, die alle verfügbaren Details abruft, unabhängig davon, ob es sich bei dem Objekt um ein Parentoder um Folgendes handelt Child:
parent.getEmployeeDetails();
Der folgende Code:
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();
}
Wird zur Ausgabe führen:
Name: 1
Name: 2 Salary: 2000
Wir haben a Childals Parent. Es hatte ein spezielles Verhalten, das für die ChildKlasse einzigartig war , aber als wir getEmployeeDetails()anriefen, konnten wir den Unterschied ignorieren und uns darauf konzentrieren, wie Parentund Childähnlich sind. Dies wird als Subtyp-Polymorphismus bezeichnet .
In Ihrer aktualisierten Frage wird gefragt, warum Child.salarynicht zugänglich ist, wenn das ChildObjekt in einer ParentReferenz gespeichert ist . Die Antwort ist der Schnittpunkt von "Polymorphismus" und "statischer Typisierung". Da Java zur Kompilierungszeit statisch typisiert ist, erhalten Sie bestimmte Garantien vom Compiler, müssen jedoch im Austausch Regeln befolgen, da der Code sonst nicht kompiliert wird. Hier besteht die relevante Garantie darin, dass jede Instanz eines Subtyps (z. B. Child) als Instanz seines Supertyps (z Parent. B. ) verwendet werden kann. Beispielsweise wird Ihnen garantiert, dass beim Zugriff employee.getEmployeeDetailsoder employee.namebeim Definieren der Methode oder des Felds für jedes Nicht-Null-Objekt, das einer Variablen employeevom Typ zugewiesen werden könnteParent . Um diese Garantie zu gewährleisten, berücksichtigt der Compiler nur diesen statischen Typ (im Grunde den Typ der Variablenreferenz).Parent ), wenn er entscheidet, auf was Sie zugreifen können. Sie können also nicht auf Mitglieder zugreifen, die für den Laufzeittyp des Objekts definiert sind Child.
Wenn Sie wirklich wollen , eine verwenden , Childals Parentdies ist eine einfache Einschränkung zu leben und Ihr Code für verwendbar sein Parentund alle Subtypen. Wenn dies nicht akzeptabel ist, geben Sie den Typ der Referenz an Child.