Programmieren-14-Vererbung und Polymorphie.pptx

Werbung
19.12.13
Vorlesung „Programmieren“
Vererbung und Polymorphismus
Prof. Dr. Stefan Fischer
Institut für Telematik, Universität zu Lübeck
http://www.itm.uni-luebeck.de/people/fischer
Bisher: Klassen und Objekte
•  Haupteigenschaften: Abstraktion und Kapselung
•  Abstraktion
–  Klassen stellen die benötigen Methoden zur Verfügung
–  Attribute werden (idealerweise) ausschließlich über Methodenaufrufe
verändert
–  Interne Funktionsweise wird versteckt
•  Kapselung (data hiding)
–  Daten und Funktionen bilden eine integrale Einheit
–  Kapselung ist das Ergebnis der Abstraktion
•  Beispiel: Klasse „Punkt“
–  Beispiel: Punkt (rotiere und verschiebe)
–  Nach außen ist nur die Schnittstelle sichtbar, nicht die Attribute
Security - 04 Cryptology
#2
Was ist mit ähnlichen Klassen?
•  Beispiel: Klassen „Auto“ und „Bus“
•  Haben einige gemeinsame Attribute
– 
– 
– 
– 
Hersteller
Wechselintervall
Gefahrene Kilometer
Baujahr
•  Aber auch Unterschiede
–  Auto: Cabriodach, ...
–  Bus: Toilette, ...
Bildquelle (Porsche): Oliver Kurmis, http://de.wikipedia.org/w/index.php?title=Datei:1962_Porsche_911.jpg&filetimestamp=20100321221316
Security - 04 Cryptology
#3
1
19.12.13
Was ist mit ähnlichen Klassen?
•  Bisherige Lösungsoptionen
–  Option 1: Implementieren zweier getrennter Klassen
–  Option 2: Implementieren einer gemeinsamen Klasse mit allen Attributen von
Auto und Bus
•  Beides ist nicht wirklich schön
–  Wird das Programm korrigiert oder verändert, müssen unter Umständen alle
Klassen angepasst werden
•  Lösung: Vererbung
Bildquelle (Porsche): Oliver Kurmis, http://de.wikipedia.org/w/index.php?title=Datei:1962_Porsche_911.jpg&filetimestamp=20100321221316
Security - 04 Cryptology
#4
Vererbung
Vererbung
•  Man versucht, zu ähnlichen Klassen eine
gemeinsame Oberklasse zu finden
•  Fasst Ähnlichkeiten zusammen
–  In Form von Attributen, Verhalten (Methoden),
Beziehungen zu anderen Klassen
•  Ergänzt in den Unterklassen lediglich die
Unterschiede
–  Ergänzende Attribute, Methoden, Beziehungen zu
anderen Klassen
5-2-6
2
19.12.13
Vererbung
•  Gemeinsamkeiten ähnlicher Klassen werden zu einer
Oberklasse zusammengefasst
Fahrzeug
hersteller: String
wechselintervall: int
km_gefahren: int
baujahr: int
wechsleOel()
Gemeinsame
Oberklasse
Bus
PKW
hersteller: String
wechselintervall: int
km_gefahren: int
baujahr: int
toilette: boolean
hersteller: String
wechselintervall: int
km_gefahren: int
baujahr: int
Bauart: String
Gemeinsamkeiten
wechsleOel()
oeffneDach() : boolean
wechsleOel()
leereToilette()
5-2-7
Vererbung: Grafische Notation
•  Unterklassen zeigen auf Oberklasse
Fahrzeug
hersteller: String
wechselintervall: int
km_gefahren: int
baujahr: int
wechsleOel()
Bus
PKW
bauart: String
toilette: boolean
leereToilette()
oeffneDach(): boolean
5-2-8
Vererbung: Ausdrucksweise
•  Fahrzeug ist Oberklasse (Superclass) bzw. Generalisierung von Bus und
PKW
•  Bus und PKW sind Unterklassen (Subclasses) bzw. Spezialisierungen von
Fahrzeug
Fahrzeug
hersteller: String
wechselintervall: int
km_gefahren: int
baujahr: int
wechsleOel()
Bus
toilette: boolean
leereToilette()
PKW
bauart: String
oeffneDach(): boolean
5-2-9
3
19.12.13
Vererbung: Ausdrucksweise
•  Pfeile deuten eine „ist ein“-Beziehung an
Bus „ist ein“ Fahrzeug
Aber: nicht jedes
Fahrzeug
ist ein Bus
Fahrzeug
PKW „ist ein“ Fahrzeug
hersteller: String
wechselintervall: int
km_gefahren: int
baujahr: int
Aber: nicht jedes
Fahrzeug
ist ein PKW
wechsleOel()
Bus
PKW
bauart: String
toilette: boolean
leereToilette()
oeffneDach(): boolean
5-2-10
Vererbung
•  Unterklassen erben von ihrer Oberklasse
–  Erben alle Attribute und Methoden
–  Kann Oberklasse um weitere Attribute und Methoden
ergänzen
•  Erben bedeutet
–  Attribute und Methoden der Oberklasse können in der
Unterklasse verwendet werden
–  Aus Sicht der Unterklasse wirkt es, als wären sie in der
Unterklasse selbst definiert
5-2-11
Vererbung in Java
•  Vererbung wird über Schlüsselwort
extends angegeben
Fahrzeug
...
–  Man kann von genau einer Oberklasse erben
–  Andere Programmiersprachen erlauben
auch von mehreren Oberklassen zu erben (C
++, ...)
•  Syntax: class Unterklasse extends Oberklasse {...} ...
Bus
PKW
...
...
...
...
•  Beispiel
–  class Bus extends Fahrzeug {...} –  class PKW extends Fahrzeug {...} 5-2-12
4
19.12.13
Vererbungshierarchie
•  Vererbung kann auch über mehrere
Hierarchiestufen erfolgen
Gegenstand
–  Vererbung von Attributen und Methoden erfolgt
transitiv
...
...
•  Beispiel
Fahrzeug
–  Fahrzeug erbt alles von Gegenstand
–  Bus und PKW erben alles von Fahrzeug
und damit auch alles von Gegenstand
•  Umsetzung in Java
–  class Fahrzeug extends Gegenstand {...} –  class Bus extends Fahrzeug {...} –  class PKW extends Fahrzeug {...}
...
...
Bus
PKW
...
...
...
...
5-2-13
Vererbung in Java
Object
...
•  In Java gibt es eine Oberklasse aller Klassen
–  java.lang.Object ...
Gegenstand
...
•  Wenn keine Oberklasse angegeben ist, wird
Object automatisch zur Oberklasse
–  Konsequenz: java.lang.Object ist
Oberklasse jeder Klasse
–  Vielleicht nicht direkt, aber irgendwann auf
jeden Fall
•  Dies ist nicht in allen Programmiersprachen so
–  z.B. nicht in C++
...
Fahrzeug
...
...
Bus
PKW
...
...
...
...
Security - 04 Cryptology
#14
Vererbung und Instanzen
•  Von jeder Klasse können Instanzen erzeugt werden
•  Diese können ganz normal verwendet werden
•  Beispiele
–  Fahrzeug f = new Fahrzeug(); f.wechsleOel(); Fahrzeug
...
–  Bus b = new Bus(); b.wechsleOel(); b.leereToilette(); ...
–  PKW p = new PKW(); p.wechsleOel(); p.oeffneDach(); Security - 04 Cryptology
Bus
PKW
...
...
...
...
#15
5
19.12.13
Vererbung und Instanzen: Darstellung
• 
• 
Syntax: Instanzname: Klassenname Syntax (Attribute): Attributname = Wert f: Fahrzeug
hersteller = "Honda"
wechselintervall = 5000
km_gefahren = 542
baujahr = 2003
Fahrzeug
hersteller: String
wechselintervall: int
km_gefahren: int
baujahr: int
b: Bus
wechsleOel()
hersteller = "MAN"
wechselintervall = 20000
km_gefahren = 4243
baujahr = 1999
toilette = true
Instanziierung
Bus
PKW
leereToilette()
p: PKW
bauart: String
toilette: boolean
hersteller = "VW"
wechselintervall = 10000
km_gefahren = 433
baujahr = 2005
bauart = "Cabrio"
oeffneDach(): boolean
5-2-16
Vererbung und Instanzen
•  Merkregel: Vererbungsbeziehung drückt eine „ist ein“ Beziehung aus
–  Beispiel: Ein PKW ist ein Fahrzeug
–  Aber: Nicht jedes Fahrzeug ist ein PKW
•  Variablen der Basisklasse können auf Referenzen der Subklassen verweisen
–  Fahrzeug f = new Fahrzeug(); –  Fahrzeug f1 = new PKW(); Fahrzeug
–  Fahrzeug f2 = new Bus(); ...
–  Bus b = new Bus(); Fahrzeug f3 = b; ...
•  Aber nicht umgekehrt
Bus
PKW
...
...
...
...
–  Bus b = new Fahrzeug(); //Fehler Security - 04 Cryptology
#17
Schlüsselwort „super“
•  Jede Instanz hat eine Referenz
auf „Ober-Instanz“
Gegenstand
...
–  z.B. um Attribute und Methoden
explizit zu referenzieren
–  Diese heißt „super“
super
...
Fahrzeug
•  Erfüllt ähnlichen Zweck zum
Zugriff auf Elemente der
Oberinstanz wie „this“ für die
aktuelle Instanz
...
...
super
•  Kann nicht wie this ausgegeben
werden (zeigt auf dieselbe
Instanz)
Security - 04 Cryptology
super
Bus
PKW
...
...
...
...
#18
6
19.12.13
Aufruf des „super“-Konstruktors
•  Aufruf des Konstruktors der Oberklasse
–  Nur aus Konstruktor möglich
–  Muss erster Aufruf im Konstruktor sein
•  Syntax: super(…evtl. Parameter…) –  class Fahrzeug { Fahrzeug(int i) { /* Code des Konstruktors */ } } –  class Bus extends Fahrzeug { Bus() { super(1); } } Security - 04 Cryptology
#19
Aufruf des „super“-Konstruktors: Beispiel
Ruft Konstruktor von „Object“ auf
Security - 04 Cryptology
#20
Aufruf der Super-Methode
•  Ruft Methode der Oberklasse auf
–  Nur möglich im Konstruktor und in Methoden
•  Ohne super würde die Methode der aktuellen
Klasse aufgerufen
•  Syntax
–  super.methodenName(…evtl. Parameter…) Security - 04 Cryptology
#21
7
19.12.13
Aufruf der Super-Methode: Beispiel
Security - 04 Cryptology
#22
Zugriff auf Super-Attribute
•  Greift auf Attribut der Oberklasse zu
•  Ohne super würde (falls vorhanden) das
Attribut in der aktuellen Klasse verwendet
werden
•  Syntax: super.attributName = 123; Security - 04 Cryptology
#23
Zugriff auf Super-Attribute: Beispiel
Security - 04 Cryptology
#24
8
19.12.13
Modifier
Modifier
•  Wichtig bei Objektorientierung: „information hiding“
–  Jeder soll nur das verwenden können, was relevant ist
–  Trägt zur Übersichtlichkeit und Fehlersicherheit bei
•  Zugriffsbeschränkung wird über sog. Modifier gesteuert
–  Schlüsselwörter: public, protected, private, „nichts“
•  Möglich für
– 
– 
– 
– 
Klassen
Attribute
Konstruktoren
Methoden
Klasse Obst
•  Attribute
–  Gewicht
• double gewichtInKg;
•  Methoden
–  double getGewichtInKg(); •  Gibt Gewicht dieser Obstinstanz zurück
9
19.12.13
package de.uzl.itm.prog.modifierbsp;
public class Obst {
Beispiel: Klasse Obst
private double gewichtInKg;
public Obst(double gewichtInKg) {
this.gewichtInKg = gewichtInKg;
}
Private Attribute:
Nur aus Klasse
zugreifbar
public double getGewichtInKg() {
return gewichtInKg;
}
}
Öffentlicher
Konstruktor und
Methode: Von
überall aus
aufrufbar
Obst obst1 = new Obst(0.346);
obst1.gewichtInKg = 0.752;
obst1.getGewichtInKg();
Beispiel: Klasse Obst
Ok, da
öffentlicher
Konstruktor
Nicht möglich,
da das Attribut
privat ist
Ok, da
Methode
öffentlich ist
Modifier
Zugriff möglich von …
Klasse Package
Modifier
public
protected*
Keine Angabe:
„package private“
private*
þ
þ
þ
þ
þ
þ
þ **
ý
Unterklasse
þ
þ
ý **
ý
Überall
þ
ý
ý
ý
*) Nicht für Klassen (nur für Attribute, Konstruktoren und Methoden)
**) Je nachdem ob Unterklasse im selben Package oder nicht
10
19.12.13
Klasse Apfel
•  Attribute
–  Preis pro kg
•  double preisProKg; •  Methoden
–  Apfel(double gewichtInKg, double preisProKg) •  Konstruktor mit gewichtInKg und preisProKg
•  Initialisiert die Attribute
–  double getPreisInEuro(); •  Berechnet Preis basierend auf Gewicht und Gewicht pro kg
package de.uzl.itm.prog.modifierbsp;
public class Apfel extends Obst {
Beispiel: Klasse Apfel
private double preisProKg;
public Apfel(double gewichtInKg,
double preisProKg) {
super(gewichtInKg);
this.preisProKg = preisProKg;
}
public double getPreis() {
return gewichtInKg * preisProKg;
}
}
Problem:
Zugriff auf
privates Attribut
der Oberklasse
nicht möglich
package de.uzl.itm.prog.modifierbsp;
public class Obst {
Beispiel: Klasse Obst
protected double gewichtInKg;
public Obst(double gewichtInKg) {
this.gewichtInKg = gewichtInKg;
}
Lösung:
Zugriff für
Unterklassen
erlauben
public double getGewichtInKg() {
return gewichtInKg;
}
}
11
19.12.13
package de.uzl.itm.prog.modifierbsp;
public class Obst {
Beispiel: Klasse Obst
protected double gewichtInKg;
public Obst(double gewichtInKg) {
this.gewichtInKg = gewichtInKg;
}
Alternative:
„package private“
erlaubt Zugriff im
selben Package
public double getGewichtInKg() {
return gewichtInKg;
}
}
Beispiel: Klasse Obst
Obst obst1 = new Obst(0.346);
obst1.gewichtInKg = 0.752;
obst1.getGewichtInKg();
Achtung!,
Zugriff jetzt
möglich, da
Klasse Main im
selben
Package
Polymorphismus
12
19.12.13
Polymorphismus
•  Methoden von Oberklassen können in Unterklassen
redefiniert werden
•  Überladen (Overloading)
–  Methode mit gleichem Namen und unterschiedlichen
Parametern
–  Rückgabetyp bleibt gleich
•  Überschreiben (Overriding) à Polymorphismus
–  Gleiche Signatur einer Methode in einer Unterklasse
–  Nach außen gleiches Interface, aber anderes Verhalten
Überladen (altes Beispiel)
•  Gleicher Methodenname und Rückgabetype, andere Parameterliste
–  void gebeAus(int i); –  void gebeAus(String s); –  void gebeAus(double d); •  Verwendung
–  gebeAus(1);
//Aufruf von void gebeAus(int i); –  gebeAus(“Hallo“);
//Aufruf von void gebeAus(String s); –  gebeAus(2.098); //Aufruf von void gebeAus(double d); •  Wesentliches Prinzip: Aufruf der „passenden“ Methode basierend auf
den Typen der übergebenen Parameter
Security - 04 Cryptology
#38
Überschreiben
Beispiel:
Was passiert?
•  class Fahrzeug { •  Welche Methode wird
void motorAn() {...} aufgerufen?
} •  Die aus Fahrzeug oder die
•  class PKW extends aus PKW?
Fahrzeug { void motorAn() {...} •  Anders gefragt: Was ist
} relevant?
•  Fahrzeug f = new PKW(); f.motorAn(); –  Der Typ der Referenz f?
–  Der Typ der Instanz, die f
referenziert?
Security - 04 Cryptology
#39
13
19.12.13
Überschriebene Methoden
•  In Java entscheidet immer der Typ der referenzierten Instanz
•  Fahrzeug f = new Fahrzeug(); f.motorAn(); –  Methode aus Klasse Fahrzeug
•  Fahrzeug f = new PKW(); f.motorAn(); –  Methode aus Klasse PKW
•  Fahrzeug f = new Bus(); f.motorAn(); –  Methode aus Klasse Bus
Security - 04 Cryptology
#40
Polymorphismus: Beispiel
•  Implementierung eines Obstkorbs
–  Menge von Früchten „speichern“
–  Preisberechnung (Gesamtpreis)
Benötigte Klassen
•  Obst (Oberklasse)
–  Wir wollen „Obst“ in den Obstkorb tun
•  Apfel (Unterklasse von Obst)
•  Birne (Unterklasse von Obst)
•  Obstkorb
–  Speichert Instanzen von Obst
14
19.12.13
Klasse Obst
•  Methode gibt Fehler (-1) zurück
–  Das abstrakte Konzept Obst kostet ja nichts
Public,
damit sie
„von
außen“
aufgerufen
werden
kann
Security - 04 Cryptology
#43
package de.uzl.itm.prog.modifierbsp;
public class Apfel extends Obst {
Beispiel: Klasse Apfel
private double preisProKg;
public Apfel(double gewichtInKg,
double preisProKg) {
super(gewichtInKg);
this.preisProKg = preisProKg;
}
Überschriebene
Methode
public double getPreis() {
return gewichtInKg * preisProKg;
}
}
Klasse Birne
•  Attribute
–  Preis pro kg
•  double preisProKg; •  Methoden
–  Birne(double gewichtInKg, double preisProKg) •  Konstruktor mit gewichtInKg und preisProKg
•  Initialisiert die Attribute
–  double getPreisInEuro(); •  Berechnet Preis basierend auf Gewicht und Gewicht pro kg
15
19.12.13
package de.uzl.itm.prog.modifierbsp;
public class Apfel extends Obst {
Beispiel: Klasse Birne
private double preisProKg;
public Apfel(double gewichtInKg,
double preisProKg) {
super(gewichtInKg);
this.preisProKg = preisProKg;
}
public double getPreis() {
return gewichtInKg * preisProKg;
}
Überschriebene
Methode
}
Klasse Obstkorb
•  Attribute
–  Speichert max. 10 Instanzen vom Typ Obst
(mehr Platz ist nicht)
–  Hat Array vom Typ Obst:
Obst obst[] = new Obst[10]; •  Methoden
–  boolean legeInKorb(Obst o); •  Legt eine Obst-Instanz in den Korb
–  double getGesamtPreis(); •  Berechnet Gesamtpreis des enthaltenen Obsts
Klasse Obstkorb
•  Kann 10 Instanzen von
„Obst“ speichern
–  Damit auch Apfel und
Birne
•  Berechnet Gesamtpreis
–  Ruft dazu die Methode
getPreis() aller ObstInstanzen auf
–  Durch Polymorphie wird
die Methode der
jeweiligen Instanz
aufgerufen, auf die
verwiesen wird
Security - 04 Cryptology
#48
16
19.12.13
Eine Klasse mit Main-Methode zum Testen
•  Erzeugt
–  Eine Instanz von
Obstkorb
–  Ein paar Instanzen
von Apfel und Birne
•  Legt die ObstInstanzen in den
Obstkorb
•  Gibt den
Gesamtpreis aus
Mehr Früchtchen
•  Ergänzung des
Warensortiments
•  Kiwi als neue Frucht
•  Preis nicht pro kg
sondern pro Stück
Klasse Kiwi
•  Attribute
–  Preis pro Stück
•  double preisProStueck;
•  Methoden
–  double getPreisInEuro(); –  Kiwi(double preisProStueck); 17
19.12.13
Klasse Kiwi
Security - 04 Cryptology
#52
Zusammenfassung
• 
Über Vererbung können gemeinsame Attribute, Methode, etc. ähnlicher
Klassen zusammengefasst werden
–  Unterklassen erben alle Eigenschaften der Oberklasse
–  In Java kann man von einer Oberklasse erben
–  Mit super kann man auf die Oberklasse zugreifen (Methoden, Attribute, Konstruktoren)
–  In Java ist ein Objekt ohne explizite Angabe der Oberklasse implizit von Object abgeleitet
• 
Modifier: Zugriff auf Attribute, Methoden und Konstruktoren regeln
• 
Polymorphie: andere Klassen kennen nur gemeinsame Oberklasse
–  Das Verhalten wird durch die konkrete referenzierte Instanz bestimmt
–  Es werden immer die Methoden der referenzierten Instanz aufgerufen
–  Wird durch Überschreiben von Methoden in Unterklassen erreicht
Security - 04 Cryptology
#53
18
Herunterladen