Python Language
Polymorphismus
Suche…
Grundpolymorphismus
Polymorphismus ist die Fähigkeit, eine Aktion an einem Objekt unabhängig von seinem Typ auszuführen. Dies wird im Allgemeinen durch Erstellen einer Basisklasse und durch zwei oder mehr Unterklassen implementiert, die alle Methoden mit derselben Signatur implementieren. Jede andere Funktion oder Methode, die diese Objekte bearbeitet, kann dieselben Methoden aufrufen, unabhängig davon, auf welchen Objekttyp sie angewendet wird, ohne dass zuvor eine Typprüfung durchgeführt werden muss. Wenn in der objektorientierten Terminologie die Klasse X die Klasse Y erweitert, wird Y als Superklasse oder Basisklasse und X als Unterklasse oder abgeleitete Klasse bezeichnet.
class Shape:
"""
This is a parent class that is intended to be inherited by other classes
"""
def calculate_area(self):
"""
This method is intended to be overridden in subclasses.
If a subclass doesn't implement it but it is called, NotImplemented will be raised.
"""
raise NotImplemented
class Square(Shape):
"""
This is a subclass of the Shape class, and represents a square
"""
side_length = 2 # in this example, the sides are 2 units long
def calculate_area(self):
"""
This method overrides Shape.calculate_area(). When an object of type
Square has its calculate_area() method called, this is the method that
will be called, rather than the parent class' version.
It performs the calculation necessary for this shape, a square, and
returns the result.
"""
return self.side_length * 2
class Triangle(Shape):
"""
This is also a subclass of the Shape class, and it represents a triangle
"""
base_length = 4
height = 3
def calculate_area(self):
"""
This method also overrides Shape.calculate_area() and performs the area
calculation for a triangle, returning the result.
"""
return 0.5 * self.base_length * self.height
def get_area(input_obj):
"""
This function accepts an input object, and will call that object's
calculate_area() method. Note that the object type is not specified. It
could be a Square, Triangle, or Shape object.
"""
print(input_obj.calculate_area())
# Create one object of each class
shape_obj = Shape()
square_obj = Square()
triangle_obj = Triangle()
# Now pass each object, one at a time, to the get_area() function and see the
# result.
get_area(shape_obj)
get_area(square_obj)
get_area(triangle_obj)
Wir sollten diese Ausgabe sehen:
Keiner
4
6,0
Was passiert ohne Polymorphismus?
Ohne Polymorphismus kann eine Typüberprüfung erforderlich sein, bevor eine Aktion für ein Objekt ausgeführt wird, um die richtige aufzurufende Methode zu bestimmen. Das folgende Counter-Beispiel führt dieselbe Aufgabe wie der vorherige Code aus, aber ohne Verwendung von Polymorphismus muss die Funktion get_area()
mehr Arbeit verrichten.
class Square:
side_length = 2
def calculate_square_area(self):
return self.side_length ** 2
class Triangle:
base_length = 4
height = 3
def calculate_triangle_area(self):
return (0.5 * self.base_length) * self.height
def get_area(input_obj):
# Notice the type checks that are now necessary here. These type checks
# could get very complicated for a more complex example, resulting in
# duplicate and difficult to maintain code.
if type(input_obj).__name__ == "Square":
area = input_obj.calculate_square_area()
elif type(input_obj).__name__ == "Triangle":
area = input_obj.calculate_triangle_area()
print(area)
# Create one object of each class
square_obj = Square()
triangle_obj = Triangle()
# Now pass each object, one at a time, to the get_area() function and see the
# result.
get_area(square_obj)
get_area(triangle_obj)
Wir sollten diese Ausgabe sehen:
4
6,0
Wichtige Notiz
Beachten Sie, dass die im Counter-Beispiel verwendeten Klassen "new style" -Klassen sind und von der Objektklasse implizit erben, wenn Python 3 verwendet wird. Der Polymorphismus funktioniert sowohl in Python 2.x als auch in 3.x, aber der Code zum Beispiel Polymorphismus-Countdown löst eine Ausnahme aus, wenn er in einem Python 2.x-Interpreter ausgeführt wird, weil type (input_obj) name gibt statt des Klassennamens "Instanz" zurück, wenn sie nicht explizit von einem Objekt erben, wodurch der Bereich niemals zugewiesen wird.
Ente tippen
Polymorphismus ohne Vererbung in Form von Enten-Typisierung, wie er in Python aufgrund seines dynamischen Typisierungssystems verfügbar ist. Das heißt, solange die Klassen dieselben Methoden enthalten, unterscheidet der Python-Interpreter nicht zwischen ihnen, da die einzige Prüfung der Aufrufe zur Laufzeit erfolgt.
class Duck:
def quack(self):
print("Quaaaaaack!")
def feathers(self):
print("The duck has white and gray feathers.")
class Person:
def quack(self):
print("The person imitates a duck.")
def feathers(self):
print("The person takes a feather from the ground and shows it.")
def name(self):
print("John Smith")
def in_the_forest(obj):
obj.quack()
obj.feathers()
donald = Duck()
john = Person()
in_the_forest(donald)
in_the_forest(john)
Die Ausgabe ist:
Quaaaaaack!
Die Ente hat weiße und graue Federn.
Die Person ahmt eine Ente nach.
Die Person nimmt eine Feder vom Boden und zeigt sie.