polymorphismus

Polymorphismus – überladen von Operatoren in Python

Ein wichtiges Konzept der objektorientierten Programmierung ist der Polymorphismus (bzw. die Polymorphie). Damit ist die Möglichkeit gemeint, den gleichen Namen für (mehr oder weniger) gleichartige Operationen zu verwenden, die auf Objekte unterschiedlicher Klassen angewendet werden. Man spricht auch vom Überladen (overloading) einer Operation.

Sie kennen das bereits vom Plusoperator +. Er kann auf Zahlen und auf Strings angewendet werden. Sind die Operanden Zahlen, bewirkt + eine Addition. Handelt es sich dagegen um Sequenzen, werden die Operanden aneinandergehängt (konkateniert). Der Plusoperator ist also überladen.

Bei Python können Operatoren und Standardfunktionen überladen werden, indem man bei einer neuen Klasse bestimmte Methoden mit vorgegebenen Namen definiert. Diese reservierten Methodennamen beginnen und enden mit doppelten Unterstrichen. In der Tabelle sind einige dieser speziellen Methoden aufgeführt.

Der Plusoperator wird z.B. durch die Methode __add__() repräsentiert. Wenn man in einer Klasse eine Methode mit diesem Namen definiert, kann der Plusoperator auch auf Objekte der neuen Klasse angewendet werden.

Wir werden das nun am Beispiel der Klasse Geld ausprobieren. Die Addition zweier Geld-Objekte soll nicht mehr durch Aufruf einer Methode, sondern durch einen mathematischen Term mit Pluszeichen formuliert werden können. Ziel ist es also, dass Anweisungen der folgenden Form möglich sind:

ausgaben = hotelrechnung + mietwagen

Dazu brauchen wir nur die Methode add() in __add__() umzubenennen.

Wenn der Python-Interpreter bei der Ausführung eines Skripts nun auf ein Pluszeichen stößt und das Objekt vor dem Pluszeichen ein Objekt der Klasse Geld ist, wandelt er den Term in einen Aufruf der Methode __add__() des Geld-Objektes um.

polymorphismus
Interpretation des überladenen Plusoperators +

Die Methoden mit den doppelten Unterstrichen greifen also tief in das Verhalten des Laufzeitsystems ein.

poly
Einige reservierte Methodennamen mit doppelten Unterstrichen

In der folgenden Klassendefinition finden mehrere Überladungen statt:

Erläuterung:

#1: Mit der Methodendefinition für __add__() wird der Plusoperator überladen. Zwei Objekte geld1 und geld2 der Klasse Geld kann man also in einem Term geld1 + geld2 addieren.

#2: Hier wird ein neues Objekt namens summe als Instanz der Klasse Geld (mit neuer Identität) generiert. Dieses neue Objekt erhält als Attribut währung die Währung von self und für das Attribut betrag die währungsbereinigte Summe der Beträge self und geld. Das neue Objekt summe ist also das Rechenergebnis und wird in der return-Anweisung zurückgegeben.

#3: Durch die Definition der Methoden __lt__(), __le__() und __eq__() werden die Vergleichsoperatoren überladen. Die Methoden definieren die Vergleiche »kleiner als« (lower than), »kleiner oder gleich« (lower or equal) und »gleich« (equal). Das heißt, für zwei Objekte geld1, geld2 der Klasse Geld werden Vergleiche wie geld1 == geld2 oder geld1 <= geld2 sinnvoll ausgewertet.

#4: Alle drei Methoden geben Wahrheitswerte zurück. Zum Beispiel wird in Zeile #4 der Wert True zurückgegeben, wenn a < b gilt, und False sonst.

#5: Mit der Methode __str__() wird eine Repräsentation von Objekten der Klasse Geld als String definiert. Damit ist es z.B. möglich, die print()-Funktion auf Objekte der Klasse Geld anzuwenden.

Anwendung:

poly

Zum Schluss sei noch darauf hingewiesen, dass auch die __init__()-Methode im Grunde eine Überladung ist, nämlich eine Überladung des Zuweisungsoperators =, der verwendet wird, um eine Instanz einer Klasse zu generieren.


python

Dieser Artikel ist ein Auszug aus dem Buch „Python 3“ von Michael Weigend. Alle Infos zum Buch, das Inhaltsverzeichnis und eine kostenlose Leseprobe findet ihr bei uns im Shop.

Kommentar verfassen