Upload
others
View
4
Download
0
Embed Size (px)
Citation preview
Martin Griebl Universität Passau
Programmieren I
Kapitel 8.Vererbung
Martin Griebl Universität Passau
Kapitel 8: Vererbung
Ziel: Wesentliches objektorientiertes Konzept kennenlernen
■ Subtypen■ Idee■ Probleme und Varianten
■ Vererbung in Java
■ dynamische Bindung
■ abstrakte Klassen
■ ggf. Interfaces
Martin Griebl Universität Passau
Subtypen Idee
■ Subtyp ist Spezialisierung des Supertyps
■ Folge: SubtypenElemente haben ■ alle Eigenschaften des Supertyps■ und noch mehr
■ Mathematisch: Subtyp ist Teilmenge des Supertyps
■ die SubtypRelation ist transitiv
■ Beispiel: ℤ
ℤg
ℕ
ℕg
Martin Griebl Universität Passau
Subtypen Problem
■ Beispiel: Funktion succ (Nachfolger, successor)■ falls nur „geerbt“: succ führt aus dem Subtyp heraus■ falls redefiniert: succ verhält sich unterschiedlich
■ Also: Vererbung im Sinne von■ Spezialisierung: eigenschaftserhaltend, aber u.U. aus dem Subtyp
herausführend■ Arbeitsersparnis: „erben“ (statt reimplementieren) was gefällt, die
anderen Sachen überschreiben
ℤ
ℤg
ℕ
ℕg
Martin Griebl Universität Passau
Subtypen Problem
■ Schwierigkeit bei Spezialisierung:■ Vögel haben als Attribut für ihre „normale“ Fortbewegungsart:
„fliegen“ – was nicht für alle Vögel stimmt■ Spezialisierungen kann (und will man daher) oft effizienter
implementieren
■ daher in Java: ■ Sicht der Arbeitsersparnis■ wobei man sich an der Idee der Spezialisierung orientiert
(„isa“Beziehung zwischen Sub und Suptertypen)
Martin Griebl Universität Passau
Subtypen
Martin Griebl Universität Passau
Subtypen in Java
■ Syntax:class <<NameSub>> extends <<NameSuper>> { ... }
■ Beispiel:class Lebewesen {...}class Tier extends Lebewesen {...}class Vogel extens Tier {...}class Saeugetier extends Lebewesen {...}class Hund extends Saeugetier {...}Hund fiffi = new Hund();Hund rex = new Hund();
Martin Griebl Universität Passau
Sub und Superklassen in Java
■ Beispiel:Tier tier = fiffi;Tier irgendeinTier = new Tier();Hund meinHund = irgendeinTier;
Martin Griebl Universität Passau
Mutierte Vererbung
■ Mit speziellen Verfahren überschreiben statt erben
■ Beispiel:class Tier { aufzucht() {...} // generelles Verfahren}class Hund { aufzucht() {...} // spezielle Verfahren}
■ rex.aufzucht(); // spezielles VerfahrenTier tier = fiffi;fiffi.aufzucht(); // ?
Martin Griebl Universität Passau
Dynamische Bindung
■ Wenn aufzucht() in einer Methode tierheim(Tier[] tiere) aufgerufen wird, weiß der Compiler nicht, welche Tiere im Heim sind. Trotzdem verwendet er jeweils die spezielle Version.
■ Bei der dynamischen Bindung entschiedet nicht die Variable (oder die Klasse, in der die Variable definiert ist), sondern die Klasse des Objekts, das aktuell in der Variable gespeichert ist.
■ Java verwendet für Methoden dynamische Bindung.
Martin Griebl Universität Passau
Dynamische Bindung nur für Methoden
■ Nochmals: aufgrund der dynamischen Bindung ist tier.aufzucht() ist jeweils die spezielle Methode, nämlich die des Objektes, das mit new erzeugt wurde.
■ Java verwendet für Attribute keine dynamsiche Bindung:
■ Gibt es in der Super und der Subklasse ein gleichnamiges Attribut x, so hat ein konkretes Objekt der Subklasse beide Attribute.
■ Zugriff mit x oder this.x im Gegensatz zu super.x
Martin Griebl Universität Passau
Weitere Bedeutung von super
■ super(...) ruft die (den Argumenttypen entsprechende) Konstruktorfunktion des Supertyps auf
■ Der Aufruf des SupertypenKonstruktors super(...) darf ausschließlich am Anfang einer Konstruktormethode des Subtypen stehen.
■ Ein Aufruf des „normalen“ Konstruktors der Superklasse ist verboten.
Martin Griebl Universität Passau
Casts
■ Wie bei Typen gibt es implizite und explizite Casts:■ implizit: vom Subtyp zum Supertyp■ explizit: vom Supertyp zum Subtyp
■ Beispiele:Hund fiffi = new Hund();Katze garfield = new Katze();Tier irgendeinTier = new Tier();Tier tier = fiffi; // implizitHund meinHund = irgendeinTier;Hund waldi = (Hund)tier; // explizitKatze mimmi = (Katze)tier;
Martin Griebl Universität Passau
Wer bist Du?
■ Problematisches Beispiel:void tierkonzert (Tier [] t) {
for (int i=0; i< t.length; i++) {// je nach Tier t[i].belle() oder t[i].miaue()
}}
■ Lösung mit instanceof:if ( t[i] instanceof Katze )
{ ((Katze)t[i]).miaue(); }if ( t[i] instanceof Hund )
{ ((Hund)t[i]).belle(); }
Martin Griebl Universität Passau
„Object“ (ganz oben) und „final“ (ganz unten)
■ Alle Klassen sind automatisch Subklassen von Object
■ Folge: equals(Object o) und toString() vordefiniert (wenngleich in der vordefinierten Version meist unbrauchbar > redefinieren empfohlen)
■ Wenn eine Klasse als final deklariert wird, kann man von ihr nicht mehr ableiten (Syntax: final class ...)
■ Zweck: überschreiben der Methoden ist damit nicht mehr möglich; sinnvoll z.B. für SecurityMonitor
■ Verfeinerung: mit final nur Methoden schützen (Syntax: final <<Typ>> <<methodenname>> {...})
Martin Griebl Universität Passau
Wiederholung „final“
■ final <<Klassendefinition>>nicht erweiterbar, damit nicht änderbar
■ final <<Methodendefinition>>nicht änderbar beim Erben
■ final <<Variablendefinition>>Konstanten: nicht änderbar im Block
■ in einer Methodendefinition: final <<Parameterdefiniton>>nicht änderbar im Rumpf; Schutz vor Missbrauch als lokale Variable
Martin Griebl Universität Passau
■ Methoden, die zur Superklasse gehören, aber für die es keine sinnvolle (einheitliche) Standarddefinition gibt, werden als abstract, d.h. ohne Rumpf, also ohne Implementierung definiert.
■ Syntax: abstract <<Typname>> <<Methodenname>> ( <<Parameterliste>> );
■ Eine Klasse, die mindestens eine abstrakte Methode enthält, heißt abstrakte Klasse.
■ Syntax: abstract <<Klassendefinition>>
■ Von abstrakten Klassen gibt es keine Objekte.
Abstrakte Methoden und abstrakte Klassen
Martin Griebl Universität Passau
Noch abstrakter: interfaces
■ Interfaces sehen aus wie abstrakte Klassen, bei denen alle Methoden abstrakt sind und die keine Attribute, sondern nur Konstanten besitzen.
■ Definition: ein Interface ist eine Sammlung von Methodenköpfen ohne Rümpfe und ggf. Konstanten.Interfaces müssen von Klassen implementiert werden.
■ Syntax:interface <<Name>> { <<Methodenköpfe>> <<Konstanten>>}
class <<Klassenname>> implements <<Interfacename>> {...}
Martin Griebl Universität Passau
Bedeutung von Interfaces
■ Interfaces definieren Schnittstellen, z.B. für Geheimnisprinzip, Anforderung an Parameter, Gruppierung von unterschiedlichen Klassen für einen gleichen Zweck
■ verschiedene Klassen können dieselbe Schnittstelle realisieren; die konkrete Implementierung ist irrelevant
■ eine Klasse kann verschiedene Interfaces implementieren, sich also entsprechend verschiedener Schnittstellen verhalten
■ Interfaces definieren (wie Klassen) neue Typen, die wie üblich zu verwenden sind
■ Interfaces sind Javas Alternative zur Mehrfachvererbung
Martin Griebl Universität Passau
Mehrfachvererbung
■ Wunsch – in Java so nicht möglich: class Auto { ... }class Boot { ... }class Amphibienfahrzeug extends Auto,Boot{
■ Problem: wenn beide Superklassen dieselbe Methode definieren, z.B. fahren(), ist nicht klar, welche die Subklasse erben soll
■ Javas Lösung: verbiete Mehrfachvererbung bei Klassen generell
■ Alternative: InterfacesAmphibienfahrzeug implements Auto, Boot {
■ Preis: nichts geerbt, d.h.: alles selber schreiben
Martin Griebl Universität Passau
Vererbung bei Interfaces
■ Interfaces erlauben Vererbung, sogar Mehrfachvererbung
■ Syntax: interface <<Name>> extends <<Name1>>, .., <<Namen>> { ...}
■ Bedeutung: der Implementierer muss alle Schnittstellen implementieren
Martin Griebl Universität Passau
Anwendung von Interfaces – Problem
public void insert ( long[] a, int w ) {int i;for (i=w; i>=1; i) {
if (a[i1] <= a[i]) { break; }swap(a,i1,i);
}}
public void insert ( Kunde[] a, int w ) {int i;for (i=w; i>=1; i) {
if (a[i1].le(a[i])) { break; }swap(a,i1,i);
}}
Martin Griebl Universität Passau
Anwendung von Interfaces – Lösung (1)
public void insert (Sortable[] a, int w) {int i;for (i=w; i>=1; i) {
if (a[i1].le(a[i])) { break; }swap(a,i1,i);
}}
interface Sortable {boolean le ( Sortable other );boolean lt ( Sortable other );boolean eq ( Sortable other );
}
Martin Griebl Universität Passau
Anwendung von Interfaces – Lösung (2)
public class Kunde implements Sortable {
private int kndnr;
public boolean le (Sortable other) {return kndnr <= ((Kunde)other).kndnr;
}
public boolean lt (Sortable other) {return kndnr < ((Kunde)other).kndnr;
}
public boolean eq (Sortable other) {return kndnr == ((Kunde)other).kndnr;
}}
Martin Griebl Universität Passau
Anwendung von Interfaces – Standard
■ Statt Sortable gibt es in java.lang ein Interface Comparable, das nur eine Methode compareTo bereitstellt und je nach Sortierung 1, 0 oder 1 zurückliefert.
■ Die „geboxten“ Typen Character, Integer, Float, ... implementieren das Interface Comparable
Martin Griebl Universität Passau
Zusammenfassung
■ Vererbung als „das“ Konzept der Objektorientierung
■ Vererbung vs. Subtyping und SubtypingProbleme
■ Super und Subtypen und Casts – von Object bis finalund mit Hilfe von instanceof
■ dynamische Bindung
■ abstrakte Klassen
■ Interfaces statt Mehrfachvererbung