Kurz: Eine Unterklasse übernimmt Felder und Methoden der Oberklasse und kann sie ergänzen oder überschreiben:
Teil des Kurses Java
Vererbung mit extends
Eine Unterklasse übernimmt Felder und Methoden der Oberklasse und kann sie ergänzen oder überschreiben:
public class Tiere {
static class Tier {
protected String name;
Tier(String name) { this.name = name; }
String laut() { return "..."; }
String vorstellen() { return name + " macht " + laut(); }
}
static class Hund extends Tier {
Hund(String name) { super(name); } // Konstruktor der Oberklasse
@Override String laut() { return "Wuff"; }
}
static class Katze extends Tier {
Katze(String name) { super(name); }
@Override String laut() { return "Miau"; }
@Override String vorstellen() { return super.vorstellen() + " (und schnurrt)"; }
}
public static void main(String[] args) {
Tier[] tiere = { new Hund("Rex"), new Katze("Mimi"), new Tier("Etwas") };
for (Tier t : tiere) System.out.println(t.vorstellen()); // Polymorphie
}
}Ausgabe:
Rex macht Wuff
Mimi macht Miau (und schnurrt)
Etwas macht ...super(...)ruft den Konstruktor der Oberklasse auf (erste Anweisung)@Overridesagt dem Compiler: “Ich überschreibe bewusst.” Er meldet Tippfehler- Polymorphie: Eine Variable vom Typ
Tierkann einenHundhalten; beim Aufruf gilt die Methode des tatsächlichen Objekts - Java erlaubt nur eine Oberklasse (keine Mehrfachvererbung von Klassen)
final classlässt sich nicht erweitern,finalbei Methoden nicht überschreiben
Abstrakte Klassen
Eine abstrakte Klasse ist nur Vorlage. Sie darf nicht instanziiert werden und kann abstrakte Methoden enthalten:
public class Formen {
static abstract class Form {
abstract double flaeche();
String info() { return getClass().getSimpleName() + " mit Fläche " + String.format("%.2f", flaeche()); }
}
static class Kreis extends Form {
double r; Kreis(double r) { this.r = r; }
double flaeche() { return Math.PI * r * r; }
}
static class Quadrat extends Form {
double a; Quadrat(double a) { this.a = a; }
double flaeche() { return a * a; }
}
public static void main(String[] args) {
for (Form f : new Form[] { new Kreis(1), new Quadrat(3) }) System.out.println(f.info());
}
}Ausgabe:
Kreis mit Fläche 3.14
Quadrat mit Fläche 9.00Interfaces
Ein Interface beschreibt einen Vertrag: welche Methoden eine Klasse anbieten muss. Eine Klasse kann mehrere Interfaces umsetzen:
public class Fahrzeuge {
interface Fahrbar { void fahren(); default String art() { return "Fahrzeug"; } }
interface Ladbar { void laden(int prozent); }
static class ElektroAuto implements Fahrbar, Ladbar {
private int akku = 20;
public void fahren() { System.out.println("surr, Akku " + akku + "%"); }
public void laden(int p) { akku = Math.min(100, akku + p); }
@Override public String art() { return "Elektroauto"; }
}
static class Fahrrad implements Fahrbar {
public void fahren() { System.out.println("tret tret"); }
}
public static void main(String[] args) {
ElektroAuto e = new ElektroAuto();
e.laden(50);
Fahrbar[] alle = { e, new Fahrrad() };
for (Fahrbar f : alle) { f.fahren(); System.out.println(f.art()); }
}
}Ausgabe:
surr, Akku 70%
Elektroauto
tret tret
FahrzeugSeit Java 8 dürfen Interfaces default-Methoden mit Standardverhalten und static-Methoden enthalten.
Interface oder abstrakte Klasse?
| Interface | Abstrakte Klasse | |
|---|---|---|
| Anzahl pro Klasse | beliebig viele | eine |
| Felder mit Zustand | nein (nur Konstanten) | ja |
| Konstruktor | nein | ja |
| Gedacht für | Fähigkeiten (“kann fahren”) | gemeinsame Basis (“ist ein Tier”) |
Programmieren gegen Interfaces
Deklariere Variablen und Parameter möglichst mit dem Interface-Typ, nicht mit der konkreten Klasse. Dann lässt sich die Umsetzung später austauschen:
import java.util.*;
public class Schnittstelle {
interface Rabatt { double anwenden(double preis); }
static double endpreis(double preis, Rabatt r) { return r.anwenden(preis); }
public static void main(String[] args) {
List<String> liste = new ArrayList<>(); // Variable: List (Interface), Objekt: ArrayList
liste.add("a");
Rabatt zehnProzent = p -> p * 0.9; // Lambda als Implementierung
Rabatt festbetrag = p -> p - 5;
System.out.println(endpreis(100, zehnProzent) + " " + endpreis(100, festbetrag));
}
}Ausgabe:
90.0 95.0Ein Interface mit genau einer abstrakten Methode heißt funktionales Interface und lässt sich mit einem Lambda ausdrücken (siehe Streams).
Komposition statt Vererbung
Vererbung koppelt Klassen eng. Oft ist es besser, ein Objekt zu haben, statt eins zu sein: Ein Auto hat einen Motor, es ist keiner.
public class Komposition {
interface Motor { String start(); }
static class Benzin implements Motor { public String start() { return "brumm"; } }
static class Elektro implements Motor { public String start() { return "surr"; } }
static class Auto {
private final Motor motor;
Auto(Motor motor) { this.motor = motor; } // Motor wird hereingegeben
String starten() { return motor.start(); }
}
public static void main(String[] args) {
System.out.println(new Auto(new Benzin()).starten() + " " + new Auto(new Elektro()).starten());
}
}Ausgabe:
brumm surrObject: die Mutter aller Klassen
Jede Klasse erbt von Object: toString(), equals(), hashCode(), getClass().
Merke
class B extends Aerbt;super(...)ruft den Elternkonstruktor,@Overrideüberschreibt bewusst- Polymorphie: Es gilt die Methode des tatsächlichen Objekts
abstractfür Vorlagen;interfacefür Verträge und Fähigkeiten (mehrere möglich)- Programmiere gegen Interfaces, bevorzuge Komposition
- Jede Klasse erbt von
Object
Übungsaufgabe
Modelliere Mitarbeiter (abstrakt, mit gehalt()) und zwei Unterklassen. Berechne die Gehaltssumme einer gemischten Liste.
Quiz zur Selbstkontrolle
Wie viele Oberklassen kann eine Java-Klasse haben?
- Eine (richtig)
- Beliebig viele
- Zwei
- Keine
Wozu dient @Override?
- Der Compiler prüft, dass wirklich überschrieben wird (richtig)
- Es löscht die Methode der Oberklasse
- Es macht die Methode schneller
- Es ist Pflicht für jede Methode
Wann nimmst du ein Interface?
- Um eine Fähigkeit oder einen Vertrag zu beschreiben, den mehrere Klassen erfüllen (richtig)
- Um Felder zu speichern
- Um Konstruktoren zu definieren
- Um Objekte zu kopieren
Weiter im Kurs
Zurück: Klassen und Objekte
Weiter: Records, Enums und versiegelte Typen
Alle Kapitel: Java im Überblick