17.06.2014 Aufrufe

Vererbung und Polymorphismus - RRZN

Vererbung und Polymorphismus - RRZN

Vererbung und Polymorphismus - RRZN

MEHR ANZEIGEN
WENIGER ANZEIGEN

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

Hurra! Ihre Datei wurde hochgeladen und ist bereit für die Veröffentlichung.

Erfolgreich gespeichert!

Leider ist etwas schief gelaufen!