A
a Top-Level-Klasse in Ihrer Hierarchie. Es sieht nur die Methoden, die darin definiert sind. Von den Unterklassen definierte Methoden sind für A
nicht zugänglich. Sicher, Sie können C
der Variablen A
zuweisen, und Sie können es dann verwenden, wo A
verwendet werden kann, aber jetzt wird C
auf Methoden beschränkt, die A
hat.
Es macht Sinn, wenn Sie darüber nachdenken. Wenn Sie einen Typ definieren (A
), erwarten Sie, dass er sich gemäß Ihrer Definition verhält (was nichts über C
Felder und Methoden enthält). Sie erwarten nicht, dass es plötzlich alles hat, was Unterklassen definiert haben könnten (stellen Sie sich zum Beispiel eine Situation vor, in der hundert Leute Ihre Klasse auf verschiedene Arten erweitert haben - Spitzenklasse würde unglaublich aufgebläht und breit werden).
Aus diesem Grund erweitern Unterklassen Elternklassen - sie fügen zusätzliche Funktionalität hinzu, die nicht im Elternteil definiert ist (und wahrscheinlich auch nicht sein sollte). Der Elternteil selbst kennt jedoch die zusätzliche Funktionalität nicht und kann sie nicht verwenden. Jede Klasse kann nur das verwenden, was sie definiert oder ihre Eltern definiert haben. Wenn Sie daher dem Typ des übergeordneten Elements C
zuweisen, werden nur die Methoden abgerufen, die A
bekannt sind (aber mit der Implementierung C
).
Bedenken Sie:
public class Animal {
public void walk() {
System.out.println("Walking");
}
}
public class Dog extends Animal {
public void bark() {
System.out.println("Woof");
}
@Override
public void walk() {
System.out.println("Doggy walk");
}
public static void main(String[] args) {
Dog dog = new Dog();
Animal animal = new Animal();
Animal animalDog = new Dog();
dog.walk(); // "Doggy walk"
dog.bark(); // "Woof"
animal.walk(); // "Walking"
animal.bark(); // Error: bark() is not defined in the Animal class
animalDog.walk(); // "Doggy walk"
animalDog.bark(); // Error - Animal class has no bark()
}
}
Da wir Dog
zu Animal
Typ zugeordnet, kann es nur Methoden, die in Animal
Klasse definiert sind. Beachten Sie jedoch, dass das Verhalten das ist, das Sie in der Klasse Dog
für dieselbe Methode definiert haben.
Wenn Sie müssen die Methode verwenden, und aus irgendeinem Grund nicht auf einen Typ zugeordnet, der die Methode hat, sollten Sie es entsprechend gegossen, z.B .:
((Dog) animalDog).bark(); // "Woof"
Ihre Variable 'a' könnte einen Verweis auf eine andere Unterklasse von' A' enthalten (wie 'D'), die keine Methode' hallo() 'liefert - der Compiler weiß es einfach nicht. Daher erlaubt der Compiler nur Aufrufe von Methoden, die für die Klasse A definiert sind. –
Identisch mit 'Object o = new String (" 123 ");' und nicht in der Lage sein, 'o.length();' zu verwenden. Wenn Sie jedoch o an einen String übergeben, können Sie die Methoden von String verwenden. –
Es klingt, als ob Sie erwarten würden, dass Ihre Definition von 'B' Ihre Definition von' A' ändert, indem Sie dessen Funktionalität "erweitern"? Denkst du darüber nach? Denn wenn das stimmt, ist das falsch. Wenn Sie 'B' und' C' definieren, tun Sie nichts mit 'A'. Eher "B" und "C" "kopieren" oder "erben" die Definition von "A" als ihren Ausgangspunkt, und dann hat alles, was Sie in ihnen definieren, auch Zugriff auf die Definition von "A". – dantiston