Java - Überschreiben
Im vorherigen Kapitel haben wir über Ober- und Unterklassen gesprochen. Wenn eine Klasse eine Methode von ihrer Oberklasse erbt, besteht die Möglichkeit, die Methode zu überschreiben, sofern sie nicht als endgültig markiert ist.
Das Überschreiben hat den Vorteil, dass ein Verhalten definiert werden kann, das für den Unterklassentyp spezifisch ist. Dies bedeutet, dass eine Unterklasse eine übergeordnete Klassenmethode basierend auf ihren Anforderungen implementieren kann.
Objektorientiert bedeutet Überschreiben, die Funktionalität einer vorhandenen Methode zu überschreiben.
Beispiel
Schauen wir uns ein Beispiel an.
class Animal {
public void move() {
System.out.println("Animals can move");
}
}
class Dog extends Animal {
public void move() {
System.out.println("Dogs can walk and run");
}
}
public class TestDog {
public static void main(String args[]) {
Animal a = new Animal(); // Animal reference and object
Animal b = new Dog(); // Animal reference but Dog object
a.move(); // runs the method in Animal class
b.move(); // runs the method in Dog class
}
}
Dies führt zu folgendem Ergebnis:
Ausgabe
Animals can move
Dogs can walk and run
Im obigen Beispiel können Sie das sehen, obwohl bist eine Tierart, die die Verschiebungsmethode in der Hundeklasse ausführt. Der Grund dafür ist: In der Kompilierungszeit wird der Referenztyp überprüft. Zur Laufzeit ermittelt JVM jedoch den Objekttyp und führt die Methode aus, die zu diesem bestimmten Objekt gehört.
Daher wird das Programm im obigen Beispiel ordnungsgemäß kompiliert, da die Animal-Klasse die Methode move hat. Zur Laufzeit wird dann die für dieses Objekt spezifische Methode ausgeführt.
Betrachten Sie das folgende Beispiel -
Beispiel
class Animal {
public void move() {
System.out.println("Animals can move");
}
}
class Dog extends Animal {
public void move() {
System.out.println("Dogs can walk and run");
}
public void bark() {
System.out.println("Dogs can bark");
}
}
public class TestDog {
public static void main(String args[]) {
Animal a = new Animal(); // Animal reference and object
Animal b = new Dog(); // Animal reference but Dog object
a.move(); // runs the method in Animal class
b.move(); // runs the method in Dog class
b.bark();
}
}
Dies führt zu folgendem Ergebnis:
Ausgabe
TestDog.java:26: error: cannot find symbol
b.bark();
^
symbol: method bark()
location: variable b of type Animal
1 error
Dieses Programm gibt einen Kompilierungszeitfehler aus, da der Referenztyp Animal von b keine Methode mit dem Namen bark hat.
Regeln zum Überschreiben von Methoden
Die Argumentliste sollte genau der der überschriebenen Methode entsprechen.
Der Rückgabetyp sollte derselbe oder ein Untertyp des Rückgabetyps sein, der in der ursprünglich überschriebenen Methode in der Oberklasse deklariert wurde.
Die Zugriffsebene kann nicht restriktiver sein als die Zugriffsebene der überschriebenen Methode. Beispiel: Wenn die Superklassenmethode als öffentlich deklariert ist, kann die überschreibende Methode in der Unterklasse weder privat noch geschützt sein.
Instanzmethoden können nur überschrieben werden, wenn sie von der Unterklasse geerbt werden.
Eine als final deklarierte Methode kann nicht überschrieben werden.
Eine als statisch deklarierte Methode kann nicht überschrieben, sondern erneut deklariert werden.
Wenn eine Methode nicht vererbt werden kann, kann sie nicht überschrieben werden.
Eine Unterklasse innerhalb desselben Pakets wie die Oberklasse der Instanz kann jede Oberklassenmethode überschreiben, die nicht als privat oder endgültig deklariert ist.
Eine Unterklasse in einem anderen Paket kann nur die nicht endgültigen Methoden überschreiben, die als öffentlich oder geschützt deklariert wurden.
Eine überschreibende Methode kann alle nicht aktivierten Ausnahmen auslösen, unabhängig davon, ob die überschriebene Methode Ausnahmen auslöst oder nicht. Die überschreibende Methode sollte jedoch keine geprüften Ausnahmen auslösen, die neu oder umfassender sind als die von der überschriebenen Methode deklarierten. Die überschreibende Methode kann engere oder weniger Ausnahmen als die überschriebene Methode auslösen.
Konstruktoren können nicht überschrieben werden.
Verwenden des Super-Schlüsselworts
Beim Aufrufen einer Superklassenversion einer überschriebenen Methode wird die super Schlüsselwort wird verwendet.
Beispiel
class Animal {
public void move() {
System.out.println("Animals can move");
}
}
class Dog extends Animal {
public void move() {
super.move(); // invokes the super class method
System.out.println("Dogs can walk and run");
}
}
public class TestDog {
public static void main(String args[]) {
Animal b = new Dog(); // Animal reference but Dog object
b.move(); // runs the method in Dog class
}
}
Dies führt zu folgendem Ergebnis:
Ausgabe
Animals can move
Dogs can walk and run