Java Method Overriding: Superclass-gedrag aanpassen
In het vorige hoofdstuk spraken we over superklassen en subclasses. Als een klasse een methode van zijn superclass overneemt, dan is er een kans om de methode te overschrijven (override), mits deze niet final is gemarkeerd.
Het voordeel van overriding is: de mogelijkheid om een gedrag te definiëren dat specifiek is voor het subtype van de subclass, wat betekent dat een subclass een methode van de parent-klasse kan implementeren op basis van zijn eigen vereisten.
In object-georiënteerde termen betekent overriding: de functionaliteit van een bestaande methode overschrijven.
Voorbeeld
class Animal {
public void move() {
System.out.println("Dieren kunnen bewegen");
}
}
class Dog extends Animal {
public void move() {
System.out.println("Honden kunnen lopen en rennen");
}
}
public class TestDog {
public static void main(String args[]) {
Animal a = new Animal(); // Animal referentie en object
Animal b = new Dog(); // Animal referentie maar Dog object
a.move(); // roept methode in Animal klasse aan
b.move(); // roept methode in Dog klasse aan
}
}
Resultaat:
Dieren kunnen bewegen Honden kunnen lopen en rennen
In het bovenstaande voorbeeld zie je dat zelfs al b van type Animal is, de move-methode in de Dog-klasse wordt uitgevoerd. De reden: tijdens compilatie wordt de controle uitgevoerd op het referentietype. Tijdens runtime bepaalt de JVM het objecttype en voert de methode uit die bij dat specifieke object hoort.
Daarom compileert het programma correct omdat de Animal-klasse de move-methode heeft. Tijdens runtime wordt de methode uitgevoerd die specifiek is voor dat object.
Belangrijk voorbeeld
class Animal {
public void move() {
System.out.println("Dieren kunnen bewegen");
}
}
class Dog extends Animal {
public void move() {
System.out.println("Honden kunnen lopen en rennen");
}
public void bark() {
System.out.println("Honden kunnen blaffen");
}
}
public class TestDog {
public static void main(String args[]) {
Animal a = new Animal();
Animal b = new Dog();
a.move();
b.move();
b.bark(); // Compileerfout!
}
}
Resultaat:
TestDog.java:26: error: cannot find symbol b.bark(); ^ symbol: method bark() location: variable b of type Animal 1 error
Deze programma geeft een compileerfout omdat het referentietype Animal geen methode bark() heeft.
Regels voor Method Overriding
- De argumentenlijst moet exact hetzelfde zijn als die van de overschreven methode.
- Het returntype moet hetzelfde zijn of een subtype van het returntype dat in de oorspronkelijke overschreven methode in de superclass is gedeclareerd.
- Het toegangsniveau mag niet restrictiever zijn dan dat van de overschreven methode. Bijvoorbeeld: als de superclass-methode
publicis, mag de overschrijvende methode in de subclass geenprivateofprotectedzijn. - Instantiemethodes kunnen alleen worden overschreven als ze door de subclass worden overgeërfd.
- Een methode gedeclareerd als final kan niet worden overschreven.
- Een methode gedeclareerd als static kan niet worden overschreven, maar wel hergedeclareerd (method hiding).
- Als een methode niet kan worden overgeërfd, kan deze niet worden overschreven.
- Een subclass in hetzelfde pakket als de superclass kan elke superclass-methode overschrijven die niet
privateoffinalis. - Een subclass in een ander pakket kan alleen de niet-final methodes overschrijven die
publicofprotectedzijn. - Een overschrijvende methode mag elke unchecked exception gooien, ongeacht of de overschreven methode uitzonderingen gooit of niet. De overschrijvende methode mag echter geen checked exceptions gooien die nieuw of breder zijn dan die gedeclareerd door de overschreven methode. De overschrijvende methode mag nauwere of minder uitzonderingen gooien.
- Constructors kunnen niet worden overschreven.
Het super-sleutelwoord gebruiken
Bij het aanroepen van de superclass-versie van een overschreven methode wordt het super-sleutelwoord gebruikt.
Voorbeeld
class Animal {
public void move() {
System.out.println("Dieren kunnen bewegen");
}
}
class Dog extends Animal {
public void move() {
super.move(); // roept de superclass methode aan
System.out.println("Honden kunnen lopen en rennen");
}
}
public class TestDog {
public static void main(String args[]) {
Animal b = new Dog(); // Animal referentie maar Dog object
b.move(); // roept methode in Dog klasse aan
}
}
Resultaat:
Dieren kunnen bewegen Honden kunnen lopen en rennen
Java
- Java-operators beheersen: typen, syntax en praktische voorbeelden
- Java interfaces meesteren: concepten, implementatie en best practices
- Java Try-with-resources meesteren: automatische resource management uitgelegd
- Java String length() Methode: Hoe de grootte van een String op te vragen (Voorbeeld)
- Java String.indexOf() beheersen: Substrings lokaliseren & praktische voorbeelden
- Java String.charAt() begrijpen: Syntaxis, Retourtype, Exceptions en Praktisch Voorbeeld
- Java's String compareTo() Methode beheersen: Syntaxis, Use Cases en Praktische Voorbeelden
- Java String.contains() Methode: Controleren op Substrings – Praktische Voorbeelden
- Java String.endsWith() beheersen: Controleren op String-suffixen met voorbeelden
- Java String Vervanging beheersen: replace(), replaceAll() en replaceFirst() uitgelegd
- Java Static Uitgelegd: Variabelen, Methodes en Blokken – Praktische Voorbeelden