Vererbung und Polymorphismus - RRZN
Vererbung und Polymorphismus - RRZN
Vererbung und Polymorphismus - RRZN
Erfolgreiche ePaper selbst erstellen
Machen Sie aus Ihren PDF Publikationen ein blätterbares Flipbook mit unserer einzigartigen Google optimierten e-Paper Software.
Objektorientierte Programmierung mit Python –<br />
<strong>Polymorphismus</strong> <strong>und</strong> <strong>Vererbung</strong><br />
Eltern<br />
Kind<br />
Kind<br />
Kind<br />
Kind
Prinzipien der objektorientierten Programmierung<br />
<br />
<br />
<strong>Vererbung</strong><br />
Strukturierung von Klassen.<br />
Oberbegriffe beschreiben allgemeine Eigenschaften <strong>und</strong><br />
Methoden eines Objekts.<br />
Spezielle Objekte erben die allgemeinen Eigenschaften <strong>und</strong><br />
Methoden.<br />
Eltern-Kind-Beziehung.<br />
Polymorphie (Vielgestaltig):<br />
Geerbte Methoden werden an die speziellen Eigenschaften<br />
eines Objektes angepasst.<br />
Methoden sind in Abhängigkeit des Datentyps<br />
unterschiedlich implementiert.<br />
Objektorientierte Programmierung, 13.09.10 Seite 2
<strong>Vererbung</strong><br />
<br />
<br />
<br />
Definition von Klassen auf Basis von bestehenden Klassen.<br />
Implementierung von „ist ein“.<br />
… bildet ein hierarchisches Modell ab. Das Modell sollte<br />
maximal drei Ebenen besitzen.<br />
Objektorientierte Programmierung, 13.09.10 Seite 3
Beispiel<br />
Konto<br />
GiroKonto<br />
- dispo : float<br />
- kontonummer : string<br />
- pinnummer : string<br />
+abheben(float betrag)<br />
+einzahlen(float betrag)<br />
+eroeffnen<br />
+schliessen<br />
FestgeldKonto<br />
- laufzeit : int<br />
- zins : float<br />
Objektorientierte Programmierung, 13.09.10 Seite 4
Darstellung der <strong>Vererbung</strong><br />
<br />
<br />
<br />
<br />
Die <strong>Vererbung</strong> von Klassen kann mit Hilfe einer Baumstruktur<br />
abgebildet werden.<br />
Die Wurzel ist die Mutter aller Klassen. In Python wird die<br />
Klasse « object » genutzt.<br />
Darunter verzweigen sich die Klassen. Um so tiefer man<br />
eindringt, um so spezieller werden die Klassen. Um so näher<br />
man an der Wurzel ist, um so allgemeiner sind die Klassen.<br />
In der <strong>Vererbung</strong> werden gerichtete Beziehungen beschrieben.<br />
Ein Girokonto ist ein Konto.<br />
Ein Ballon ist ein Luftfahrzeug.<br />
Objektorientierte Programmierung, 13.09.10 Seite 5
Regeln<br />
<br />
<br />
<br />
Es werden alle Attribute <strong>und</strong> Methoden von der Basisklasse<br />
geerbt.<br />
Neue Attribute <strong>und</strong> Methoden können hinzufügt werden.<br />
Methoden aus der Basisklasse können überschrieben werden.<br />
Die Methoden aus der Basisklasse werden mit einer neuen<br />
Funktionalität versehen.<br />
Objektorientierte Programmierung, 13.09.10 Seite 6
Basis- <strong>und</strong> Subklassen<br />
Basisklasse<br />
Fahrzeuge<br />
Subklasse<br />
Land Wasser Luft<br />
Schiene<br />
Motorisiert<br />
Unmotorisiert<br />
Unmoterisiert<br />
Motorisiert<br />
Flugzeug<br />
Zeppelin<br />
Heißluftballon<br />
Objektorientierte Programmierung, 13.09.10 Seite 7
Subklasse (Unterklasse, abgeleitete Klasse) ...<br />
<br />
<br />
<br />
<br />
erbt von der Basisklasse alle Attribute <strong>und</strong> Methoden.<br />
beschreibt die speziellen Elemente einer Klasse.<br />
ist von einer anderen Klasse abgeleitet.<br />
befindet sich in der Hierarchie unterhalb einer anderen Klasse.<br />
Objektorientierte Programmierung, 13.09.10 Seite 8
Basisklasse (Oberklasse, parent class) ...<br />
<br />
<br />
<br />
<br />
<br />
ist der Ausgangspunkt für die Bildung von weiteren Klassen.<br />
implementiert Kategorien für Klassen.<br />
fasst Gemeinsamkeiten von verschiedenen Klassen<br />
zusammen.<br />
sortiert verschiedene Klassen in Schubladen ein.<br />
kann selber Subklasse einer anderen Basisklasse sein.<br />
Objektorientierte Programmierung, 13.09.10 Seite 9
Generalisierung <strong>und</strong> Spezialisierung<br />
Spezialisierung<br />
Fahrzeuge<br />
Generalisierung<br />
Land Wasser Luft<br />
Schiene<br />
Motorisiert<br />
Unmotorisiert<br />
Unmoterisiert<br />
Motorisiert<br />
Flugzeug<br />
Zeppelin<br />
Heißluftballon<br />
Objektorientierte Programmierung, 13.09.10 Seite 10
Generalisierung ...<br />
<br />
<br />
<br />
sucht Gemeinsamkeiten aller Klassen in einer<br />
Projektbeschreibung.<br />
kategorisiert Klassen.<br />
nutzt die Bottom-Up-Methode. Die Klassen werden zuerst<br />
allgemein beschrieben <strong>und</strong> anschließend in Abhängigkeit der<br />
Aufgabe spezialisiert.<br />
Objektorientierte Programmierung, 13.09.10 Seite 11
Spezialisierung ...<br />
<br />
<br />
<br />
<br />
beschreibt die Aktion „erbt von“.<br />
stellt eine „ist eine“-Beziehung dar.<br />
beschreibt exakt ein Objekt in einer Schublade.<br />
nutzt die Top-Down-Methode. Es werden zuerst alle benötigten<br />
Klassen in der Projektbeschreibung gesucht <strong>und</strong> implementiert.<br />
Anschließend werden Gemeinsamkeiten gesucht <strong>und</strong> diese in<br />
übergeordneten Klassen implementiert.<br />
Objektorientierte Programmierung, 13.09.10 Seite 12
Basisklasse in Python<br />
«<br />
class Grafik(object):<br />
ANZAHL = 0<br />
def __init__(self, x = 0, y = 0):<br />
pass<br />
def set_Pos(self, xPos, yPos):<br />
pass<br />
»<br />
def get_Pos(self):<br />
pass<br />
Objektorientierte Programmierung, 13.09.10 Seite 13
Klassenkopf einer Basisklasse ...<br />
« class Klassenname(object) ».<br />
beginnt mit dem Schlüsselwort « class ».<br />
<br />
<br />
Dem Schlüsselwort folgt der Klassenname. Der<br />
Klassenname ...<br />
ist frei wählbar.<br />
identifiziert eindeutig eine Klasse.<br />
Am Ende des Kopfes folgt die Parameterliste, begrenzt durch<br />
die r<strong>und</strong>en Klammern.<br />
Objektorientierte Programmierung, 13.09.10 Seite 14
Parameterliste<br />
« class Klassenname(object) ».<br />
<br />
<br />
<br />
beginnt <strong>und</strong> endet mit den r<strong>und</strong>en Klammern.<br />
enthält Namen von definierten Klassen. Die Elemente in der<br />
Liste werden durch Kommata getrennt.<br />
der Basisklasse ist leer oder sollte von « object » erben.<br />
Objektorientierte Programmierung, 13.09.10 Seite 15
Subklasse in Python<br />
«<br />
class Rechteck(Grafik):<br />
def __init__(self, breite = 10, hoehe = 20):<br />
Grafik.__init__(self, 0, 0)<br />
self.__height = hoehe<br />
self.__width = breite<br />
def set_Groesse(self, breite, hoehe):<br />
pass<br />
»<br />
def get_Groesse(self):<br />
pass<br />
Objektorientierte Programmierung, 13.09.10 Seite 16
Klassenkopf einer Subklasse ...<br />
« class Klassenname(basisklasse, basisklasse) ».<br />
beginnt mit dem Schlüsselwort « class ».<br />
<br />
<br />
Dem Schlüsselwort folgt der Klassenname. Der<br />
Klassenname ...<br />
ist frei wählbar.<br />
identifiziert eindeutig eine Klasse.<br />
Am Ende des Kopfes folgt die Parameterliste, begrenzt durch<br />
die r<strong>und</strong>en Klammern.<br />
Objektorientierte Programmierung, 13.09.10 Seite 17
Parameterliste<br />
« class Klassenname(basisklasse, basisklasse) ».<br />
<br />
<br />
<br />
beginnt <strong>und</strong> endet mit den r<strong>und</strong>en Klammern.<br />
enthält Namen von definierten Klassen. Die Elemente in der<br />
Liste werden durch Kommata getrennt.<br />
Eine Mehrfachvererbung ist durch die Nennung von mehreren<br />
Klassen für eine Subklasse realisierbar. Die Subklasse basiert<br />
auf mehr als eine Klasse.<br />
Objektorientierte Programmierung, 13.09.10 Seite 18
Methoden aufrufen<br />
<br />
<br />
<br />
<br />
<br />
Methoden in der Subklasse:<br />
« [subklasse].[methode](arg01, arg02) »<br />
Methoden aus der Basisklasse:<br />
« [subklasse].[methode](arg01, arg02) »<br />
Die Methode wird der Klasse durch ein Punkt verb<strong>und</strong>en.<br />
Jeder Methode können mit Hilfe der Parameterliste<br />
verschiedenen Werte übergeben werden. Die Elemente in der<br />
Liste werden durch Kommata getrennt.<br />
Die angegebene Methode wird zuerst in der Subklasse<br />
gesucht. Falls sie dort nicht vorhanden ist, werden die<br />
Basisklassen in der, in der in der Parameterliste angegebenen<br />
Reihenfolge durchsucht.<br />
Objektorientierte Programmierung, 13.09.10 Seite 19
Beispiel<br />
«<br />
# Basisklasse<br />
class Grafik(object):<br />
def set_Pos(self, xPos, yPos):<br />
pass<br />
def get_xPos(self):<br />
return self.__xPos<br />
def write_Pos(self):<br />
pass<br />
«<br />
# Subklasse<br />
class Grafik(object):<br />
def set_Groesse(self, breite, hoehe):<br />
pass<br />
def get_Groesse(self):<br />
pass<br />
def write_Groesse(self):<br />
pass<br />
»<br />
myGrafik = modul.Grafik(20,20)<br />
myGrafik.write_Pos()()<br />
»<br />
myRechteckStandard = modul.Rechteck()<br />
myRechteckStandard.write_Pos()<br />
myRechteckStandard.write_Groesse()<br />
Objektorientierte Programmierung, 13.09.10 Seite 20
Benutzerdefinierte Fehlerklasse<br />
«<br />
class clsMyError(Exception):<br />
fehlermeldung = {5000 : "Negative Zahl", 6000 : "Wert = 0"}<br />
def __init__(self, fehlerNr):<br />
self.fehlerNr = fehlerNr<br />
»<br />
def getMeldung(self):<br />
return clsMyError.fehlermeldung[self.fehlerNr]<br />
Objektorientierte Programmierung, 13.09.10 Seite 21
Hinweise<br />
<br />
<br />
<br />
Benutzerdefinierte Fehlerklassen sollten immer von der<br />
vordefinierten Klasse « exception » erben.<br />
Der Programmierer kann die Fehlerklassen aber selber<br />
gestalten.<br />
Fehlerklassen sollten möglichst einfach sein.<br />
Objektorientierte Programmierung, 13.09.10 Seite 22
Nutzung von benutzerdefinierten Fehlerklasse<br />
«<br />
import fehler_class<br />
try:<br />
divident = float(strDivident)<br />
if (divident < 0):<br />
raise fehler_class.clsMyError(5000)<br />
except fehler_class.clsMyError as e:<br />
print(e.getMeldung())<br />
»<br />
Objektorientierte Programmierung, 13.09.10 Seite 23
Polymorphie (Vielgestaltigkeit, Ähnlichkeit)<br />
<br />
<br />
… innerhalb einer Klasse:<br />
Nachbildung von mathematischen Operationen,<br />
Vergleichsoperationen etc, um die Funktionalität der Klasse<br />
an vordefinierte Klassen anzupassen.<br />
Überladung von Klassen.<br />
… bei der <strong>Vererbung</strong> von Klassen:<br />
Die Subklasse überschreibt eine Methode der Basisklasse.<br />
Die Subklasse nutzt virtuelle Methoden. Objekte einer<br />
Subklasse, die alle die gleiche Basisklasse nutzen,<br />
reagieren auf ein <strong>und</strong> dieselbe Nachricht unterschiedlich.<br />
Objektorientierte Programmierung, 13.09.10 Seite 24
Methoden überschreiben<br />
<br />
<br />
<br />
<br />
Methoden aus der Basisklasse werden überdeckt.<br />
Geerbte Methoden werden mit einer neuen Funktionalität<br />
versehen.<br />
Die Methode aus der Basisklasse wird in der Subklasse neu<br />
definiert.<br />
Konstruktoren der Basisklassen werden häufig überschrieben.<br />
Objektorientierte Programmierung, 13.09.10 Seite 25
Konstruktor überschreiben<br />
«<br />
class Grafik(object):<br />
def __init__(self, x = 0, y = 0):<br />
self.__xPos = x<br />
self.__yPos = y<br />
» «<br />
»<br />
class Rechteck(Grafik):<br />
def __init__(self, breite = 10, hoehe = 20):<br />
Grafik.__init__(self, 0, 0)<br />
self.__height = hoehe<br />
self.__width = breite<br />
self.__xPosRO = breite<br />
self.__yPosRO = hoehe<br />
Objektorientierte Programmierung, 13.09.10 Seite 26
Konstruktor einer Subklasse<br />
« def __init__(self, breite = 10, hoehe = 20) ».<br />
beginnt mit dem Schlüsselwort « def ».<br />
hat immer den Namen « __init__ »<br />
hat eine Parameterliste, die durch r<strong>und</strong>e Klammern begrenzt<br />
wird. In dieser Parameterliste werden alle zu übergebenen<br />
Parameter aufgelistet. Die Listenelemente werden durch ein<br />
Kommata getrennt.<br />
ruft zuerst den Konstruktor der Basisklasse auf « Grafik.__init__(self, 0,<br />
0) » <strong>und</strong> setzt anschließend die Objektattribute der Subklasse.<br />
Objektorientierte Programmierung, 13.09.10 Seite 27
Methode in der Basisklasse<br />
«<br />
»<br />
class Grafik(object):<br />
def set_Pos(self, xPos, yPos):<br />
self.__xPos = xPos<br />
self.__yPos = yPos<br />
Objektorientierte Programmierung, 13.09.10 Seite 28
… überschreiben<br />
«<br />
class Rechteck(Grafik):<br />
def set_Pos(self, x_LO, y_LO, x_RO = 0, y_RO = 0):<br />
abstandX = self.get_xPos() - x_LO<br />
abstandY = self.get_yPos() - y_LO<br />
super().set_Pos(x_LO, y_LO)<br />
»<br />
if (x_RO > 0):<br />
self.__width = self.__width + abstandX<br />
else:<br />
self.__xPosRO = self.get_xPos() + self.__width<br />
Objektorientierte Programmierung, 13.09.10 Seite 29
Zugriff auf Methoden der Basisklasse ...<br />
mit Hilfe der Methode « super() »:<br />
<br />
Beispiel: « super().set_Pos(x_LO, y_LO) ».<br />
Arbeitet nur mit Basisklassen zusammen, die von « object »<br />
erben.<br />
Seit Python 2.2 ist die Methode implementiert.<br />
mit Hilfe des Namens:<br />
Beispiel: « Grafik.__init__(self, 0, 0) ».<br />
Die Angabe des Objekts « self » wird immer benötigt.<br />
Objektorientierte Programmierung, 13.09.10 Seite 30
Operatoren überladen, um ...<br />
<br />
<br />
Rechenoperatoren oder Vergleichsoperatoren für<br />
benutzerdefinierte Datentypen zu implementieren.<br />
Klassen mit einer Funktionalität ähnlich wie Standard-<br />
Datentypen auszustatten.<br />
Objektorientierte Programmierung, 13.09.10 Seite 31
Beispiel<br />
<br />
<br />
Das Pluszeichen kann eine Ganzzahl oder Dezimalzahl<br />
addieren.<br />
Das Pluszeichen wurde für Strings überladen. Das Pluszeichen<br />
verkettet zwei Strings.<br />
Objektorientierte Programmierung, 13.09.10 Seite 32
Operatoren in Python<br />
<br />
Umgangssprachliche Schreibweise: summe = a + b<br />
Der Operator definiert eine Verknüpfungsvorschrift.<br />
Formale Schreibweise: summe = __add__ (a, b)<br />
Die Operatoren sind als Methoden implementiert.<br />
Der Methode « __add__ » werden zwei Objekte übergeben.<br />
Das Ergebnis der Berechnung wird zurückgegeben.<br />
Objektorientierte Programmierung, 13.09.10 Seite 33
Addition neu definieren<br />
«<br />
class Rechteck(Grafik):<br />
def __add__(self, other):<br />
breite = self.__width + other.__width<br />
hoehe = self.__height + other.__height<br />
newRechteck = Rechteck(breite, hoehe)<br />
»<br />
return newRechteck<br />
Objektorientierte Programmierung, 13.09.10 Seite 34
„Ist gleich“ neu definieren<br />
«<br />
class Rechteck(Grafik):<br />
def __eq__(self, other):<br />
proofx = self.get_xPos() == other.get_xPos()<br />
proofy = self.get_yPos() == other.get_yPos()<br />
»<br />
return (proofx and proofy)<br />
Objektorientierte Programmierung, 13.09.10 Seite 35
String definieren<br />
«<br />
»<br />
class Rechteck(Grafik):<br />
def __str__(self):<br />
ausgabe = "X-Position, oben links: " + str(self.get_xPos())<br />
ausgabe = ausgabe + "\nY-Position, oben links "+ str(self.get_yPos())<br />
ausgabe = ausgabe + "\nX-Position, unten rechts: "+ str(self.__xPosRO)<br />
ausgabe = ausgabe + "\nY-Position, unten rechts "+ str(self.__yPosRO)<br />
return ausgabe<br />
Objektorientierte Programmierung, 13.09.10 Seite 36
Aufruf der überladenen Operatoren<br />
«<br />
RechteckGross = myRechteckStandard + Rechteck_Basisklasse.Rechteck(100, 100)<br />
print("Position gleich? ", RechteckGross == RechteckPos)<br />
»<br />
print(RechteckGross)<br />
Objektorientierte Programmierung, 13.09.10 Seite 37