Polimorfizm OOP w Pythonie: pisanie kaczek i interfejsy
Opanuj polimorfizm w Pythonie. Dowiedz się, jak pisać elastyczny, luźno powiązany kod, korzystając z typowania kaczego, przesłaniania metod i abstrakcyjnych klas bazowych.
Przegląd
Polimorfizm to greckie określenie oznaczające „wiele form”. W programowaniu obiektowym odnosi się do zdolności różnych klas do reagowania na to samo wywołanie metody w swój własny, unikalny sposób. Polimorfizm pozwala na napisanie pojedynczej funkcji, która może przetwarzać wiele różnych typów obiektów, pod warunkiem, że mają one wspólny interfejs. Umożliwia to niskie sprzężenie i sprawia, że systemy oprogramowania są wysoce elastyczne i łatwe w rozbudowie.
W Pythonie polimorfizm jest głęboko powiązany z koncepcją znaną jako Duck Typing. Termin pochodzi od wyrażenia: „Jeśli coś chodzi jak kaczka i kwacze jak kaczka, to musi to być kaczka”. W dynamicznie typowanym Pythonie funkcja nie dba o to, do której klasy należy obiekt; interesuje go tylko to, czy ten obiekt implementuje żądane metody. Na przykład, jeśli masz funkcję wywołującą `.speak()`, możesz przekazać jej psa, kota lub robota — o ile wszystkie mają metodę `.speak()`, kod działa idealnie.
W przypadku bardziej rygorystycznych architektur Python udostępnia abstrakcyjne klasy bazowe (ABC) poprzez wbudowany moduł `abc`. Dziedzicząc z `abc.ABC` i używając dekoratora `@abstractmethod`, możesz zdefiniować formalne interfejsy, które klasy potomne muszą implementować. Jeśli klasa potomna nie zdefiniuje metod abstrakcyjnych, Python zgłosi błąd TypeError przy próbie utworzenia jej instancji. Równowaga elastycznego pisania kaczego z formalnymi klasami abstrakcyjnymi jest kluczową umiejętnością projektowania odpornych bibliotek Pythona.
Dane wyjściowe kodu i wykonania
Implementacja klas polimorficznych reprezentujących kształty obliczające ich powierzchnię.
from abc import ABC, abstractmethod
class Shape(ABC):
@abstractmethod
def area(self):
"""Must be implemented by subclasses."""
pass
class Square(Shape):
def __init__(self, side):
self.side = side
def area(self):
return self.side * self.side
class Circle(Shape):
def __init__(self, radius):
self.radius = radius
def area(self):
import math
return math.pi * (self.radius ** 2)
# Polymorphic function accepting any Shape
def print_area(shape: Shape):
print(f"Calculated Area: {shape.area():.2f}")
print_area(Square(4))
print_area(Circle(3))Calculated Area: 16.00
Calculated Area: 28.27Wdrażanie krok po kroku
- Pisanie procesorów płatniczych obsługujących obiekty CreditCard, PayPal i Stripe
- Rysowanie różnych elementów (tekstu, obrazu) przy użyciu ujednoliconej pętli renderowania
- Wyśmiewanie zewnętrznych połączeń API podczas testów jednostkowych
Często zadawane pytania
Co to jest pisanie kaczką?
Jest to dynamiczne podejście Pythona do polimorfizmu. Sprawdza obecność metod i właściwości w czasie wykonywania, zamiast weryfikować dziedziczenie z określonej klasy nadrzędnej.
Czy możesz utworzyć instancję abstrakcyjnej klasy bazowej?
Nie. Próba utworzenia instancji klasy dziedziczącej po ABC i zawierającej metody abstrakcyjne zgłosi błąd TypeError.
Powiązane tematy
Kompletne wprowadzenie do klas, obiektów, dziedziczenia i pojęć OOP w Pythonie. Twórz niezawodne modele danych i skaluj swoje aplikacje w Pythonie.
Dziedziczenie OOP w PythonieNaucz się dziedziczenia w Pythonie OOP. Opanuj podklasy, przesłanianie metod, używanie super() i wzorce wielokrotnego dziedziczenia.
Polecane zasoby Pythona
Poszerzaj swoją wiedzę dzięki powiązanym interaktywnym samouczkom, ściągawkom i porównaniom kodów.
Jak sortować listę w Pythonie
Dowiedz się, jak sortować listę w Pythonie za pomocą metody sort() i funkcji sorted(). Odkryj przykłady niestandardowego sortowania kluczy i odwrotnej kolejności.
Ściągawka dotycząca metod ciągów w Pythonie
Kompletny przewodnik dotyczący manipulacji ciągami znaków w języku Python. Opanuj formatowanie, wyszukiwanie, dzielenie, zastępowanie i sprawdzanie właściwości ciągów.
Python kontra JavaScript: który język programowania jest najlepszy?
Kompleksowe porównanie Pythona i JavaScript. Poznaj różnice w składni, wydajność, przypadki użycia (backend vs frontend) i przykłady kodowania.