CodeGym /Kursy /Python SELF PL /Dziedziczenie wielokrotne

Dziedziczenie wielokrotne

Python SELF PL
Poziom 16 , Lekcja 4
Dostępny

10.1 Dziedziczenie z kilku klas

Dziedziczenie wielokrotne w Pythonie pozwala klasie dziedziczyć atrybuty i metody z więcej niż jednej klasy bazowej. To daje większą elastyczność i pozwala na ponowne użycie kodu, ale może również prowadzić do skomplikowanych hierarchii i potencjalnych konfliktów.

Możliwość wymienienia pięciu rodziców dla swojej klasy znacznie rozszerza twoje możliwości i ułatwia pisanie kodu. Jest to bardzo proste — wystarczy wymienić klasy-rodzice oddzielone przecinkiem:


class Base1:
    def method1(self):
        print("Method1 from Base1")
        
class Base2:
    def method2(self):
        print("Method2 from Base2")
        
class Derived(Base1, Base2):
    pass
        
obj = Derived()
obj.method1()
obj.method2()     
        

Wszystko działa zgodnie z planem — pięknie.

Jednak dziedziczenie wielokrotne ma kilka złożonych aspektów, które musisz wziąć pod uwagę przy jego używaniu. Przyjrzyjmy się, jak to działa i jak unikać problemów związanych z dziedziczeniem wielokrotnym.

10.2 Wywołanie metody, która istnieje w kilku klasach bazowych

Klasa może dziedziczyć atrybuty i metody z kilku klas bazowych, wymienionych w nawiasach po nazwie klasy. I te atrybuty i metody mogą mieć takie same nazwy:


class Base1:
    def method(self):
        print("Method from Base1")
        
class Base2:
    def method(self):
        print("Method from Base2")
        
class Derived(Base1, Base2):
    pass
        

obj = Derived()
obj.method() # która metoda zostanie wywołana?
        

W tym przykładzie klasa Derived dziedziczy z Base1 i Base2. Kiedy wywoływana jest method(), Python wybierze metodę pierwszej wymienionej klasy — Base1.

Ale to nie jest takie oczywiste, prawda? I jeśli ktoś zmieni kod klasy bazowej, może ucierpieć cała logika aplikacji, a ty nawet nie będziesz wiedzieć, że coś jest nie tak. Po prostu zaczną być wywoływane nieco inne metody :)

10.3 Użycie super() z dziedziczeniem wielokrotnym

Kolejną ciekawą cechą jest wywołanie super() dla klasy bazowej przy dziedziczeniu wielokrotnym.

Przykład:


class Base1:
    def method(self):
        print("Method from Base1")
        super().method()
        
class Base2:
    def method(self):
        print("Method from Base2")
        super().method()
        
class Derived(Base1, Base2):
    def method(self):
        print("Method from Derived")
        super().method()
         

obj = Derived()
obj.method()
        

No i co? Jaki będzie wynik na ekranie?

Method from Derived
Method from Base1

Albo

Method from Derived
Method from Base2 

Mam dla ciebie niespodziankę — wynik będzie taki:

Method from Derived
Method from Base1
Method from Base2

Kod super().method() wywoła metodę method() u każdej klasy bazowej! To są właśnie te niuanse, o których wspominałem przy pierwszym wspomnieniu o dziedziczeniu wielokrotnym.

10.4 Diamentowe (Diamond) dziedziczenie

I wreszcie, klasyczny problem diamentowego dziedziczenia. Łatwiej to pokazać na przykładzie, niż opisywać:

W postaci kodu może to wyglądać na przykład tak:


class A:
    def method(self):
        print("Method from A")
        
class B(A):
    def method(self):
        print("Method from B")
        super().method()
        
class C(A):
    def method(self):
        print("Method from C")
        super().method()
        
class D(B, C):
    def method(self):
        print("Method from D")
        super().method()
         
         
        
obj = D()
obj.method()
        

Wynik będzie taki:

Method from D
Method from B
Method from C
Method from A 

Aby móc orientować się w dziedziczeniu wielokrotnym, musisz dobrze wiedzieć, w jakiej kolejności Python szuka pól i metod w klasach bazowych. Właśnie o tym dowiesz się na kolejnej lekcji.

Komentarze (1)
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION
Min Poziom 17, Warsaw, Poland
19 marca 2025
Cześć, czy przykład "10.3 Użycie super() z dziedziczeniem wielokrotnym" jest prawidłowy? Klasa Base1 jest klasą podstawową, nie dziedziczy po żadnej innej klasie a wywołuje metodę super().method()