Merke:
Erbt eine Klasse („Unterklasse“) von einer anderen („Oberklasse“), so übernimmt sie alle ihre Methoden und Attribute.
Im Klassendiagramm kennzeichnet man die Vererbung durch einen Pfeil mit nicht-ausgefülltem Dreieck als Spitze. Bei den Unterklassen gibt man im Diagramm nur diejenigen Attribute und Methoden an, die zusätzlich zu denen der Oberklasse hinzukommen.
public class Fahrzeug { private int radAnzahl; private double leistung; private String marke; public Fahrzeug(String marke, int radAnzahl, double leistung){ this.marke = marke; this.radAnzahl = radAnzahl; this.leistung = leistung; } public String gibDaten(){ String s = "Daten des Fahrzeugs:\n"; s = s + "Marke: " + marke + "\n"; s = s + "Leistung: " + leistung + "\n"; s = s + "Radanzahl: " + radAnzahl + "\n"; return s; } }
public class Auto extends Fahrzeug { private boolean hatKlimaanlage; public Auto(String marke, boolean hatKlimaanlage, double leistung){ super(marke, 4, leistung); this.hatKlimaanlage = hatKlimaanlage; } public String gibDaten(){ String s = super.toString(); s = s + "Klimaanlage: " + hatKlimaanlage; return s; } }
public class Motorrad extends Fahrzeug { private boolean hatBeisitzer; public Motorrad(String marke, boolean hatBeisitzer, double leistung){ super(marke, 2, leistung); this.hatBeisitzer = hatBeisitzer; } public String gibDaten(){ String s = super.toString(); s = s + "Beisitzer: " + hatBeisitzer; return s; } }
Die Klassen Auto und Motorrad überschreiben beide die Methode gibDaten() der Klasse Fahrzeug. Hat man eine Variable mit Datentyp Fahrzeug, so kann sie auf ein Objekt der Klasse Fahrzeug, Auto oder Motorrad zeigen.
Ruft man für das Objekt die Klasse gibDaten() auf, so wird – je nach Objekt – die Methode der Klasse Fahrzeug, Auto oder Motorrad ausgeführt.
Merke:
Man spricht von Polymorphismus, wenn eine Methode der Basisklasse bei mehreren Unterklassen überschrieben wird.
public class FahrzeugTest { public void test(){ Fahrzeug[] liste = new Fahrzeug[3]; liste[0] = new Auto("BMW i3", true, 140.0); liste[1] = new Motorrad("Harley", false, 180.0); liste[2] = new Auto("Audi A3", true, 120.0); for(int i = 0; i < liste.length; i++){ Fahrzeug f = liste[i]; System.out.println(f.gibDaten()); // Hier passiert die Magie! System.out.println(); } } }
Der Methodenaufruf f.gibDaten()
ruft beim ersten und dritten Objekt die Methode gibDaten()
der Klasse Auto
auf, beim zweiten Objekt die Methode gibDaten()
der Klasse Motorrad
.
Merke:
Deklariert man eine Klasse als abstract („Abstrakte Klasse“), so können keine Objekte dieser Klasse instanziert werden.
Deklariert man eine Methode von ihr als abstract („Abstrakte Methode“) und lässt den Methodenrumpf (Programmcode) weg, so muss jede nicht-abstrakte Unterklasse der Klasse diese Methode implementieren.
Im obigen Beispiel ist es nicht sinnvoll, ein Objekt der Klasse Fahrzeug instanzieren. Gleichzeitig wollen wir jede Unterklasse von Fahrzeug dazu zwingen, die Methode gibDaten() zu implementieren.
abstract public class Fahrzeug { private int radAnzahl; private double leistung; private String marke; public Fahrzeug(String marke, int radAnzahl, double leistung){ this.marke = marke; this.radAnzahl = radAnzahl; this.leistung = leistung; } protected String gibFahrzeugdaten(){ String s = "Daten des Fahrzeugs:\n"; s = s + "Marke: " + marke + "\n"; s = s + "Leistung: " + leistung + "\n"; s = s + "Radanzahl: " + radAnzahl + "\n"; return s; } abstract public String gibDaten(); }
public class Auto extends Fahrzeug { private boolean hatKlimaanlage; public Auto(String marke, boolean hatKlimaanlage, double leistung){ super(marke, 4, leistung); this.hatKlimaanlage = hatKlimaanlage; } abstract public String gibDaten(){ String s = gibFahrzeugdaten(); s = s + "Klimaanlage: " + hatKlimaanlage; return s; } }
public class Motorrad extends Fahrzeug { private boolean hatBeisitzer; public Motorrad(String marke, boolean hatBeisitzer, double leistung){ super(marke, 2, leistung); this.hatBeisitzer = hatBeisitzer; } public String toString(){ String s = gibFahrzeugdaten(); s = s + "Beisitzer: " + hatBeisitzer; return s; } }
Die Schlüsselworte public
, protected
und private
regeln die Sichtbarkeit von Methoden:
public
-Methoden sind von jeder Klasse aus sichtbar.protected
-Methoden sind nur in der Klasse selbst und in allen Unterklassen der Klasse sichtbar.private
-Methoden sind nur in der Klasse selbst sichtbar.