Python - Višestruko nasljeđivanje (Multiple Inheritance)


Python višestruko nasljeđivanje

Klasa se može izvesti iz više od jedne osnovne klase u Pythonu, slično C++. To se naziva višestruko nasljeđivanje. U višestrukom nasljeđivanju, obilježja svih osnovnih klasa nasljeđuju se u izvedenu klasu. Sintaksa za višestruko nasljeđivanje slična je pojedinačnom nasljeđivanju. Primjer višestrukog nasljeđivanja:

class Base1:
    pass

class Base2:
    pass

class MultiDerived(Base1, Base2):
    pass

Ovdje je klasa MultiDerived izvedena iz klase Base1 i Base2.




Klasa MultiDerived nasljeđuje i klase Base1 i Base2.



Python višerazinsko nasljeđivanje (Multilevel Inheritance)

Takođe možemo nasljediti iz izvedene klase. To se naziva nasljeđivanje na više nivoa. U Pythonu može biti bilo koje dubine. U višerazinskom nasljeđivanju, karakteristika osnovne klase i izvedene klase nasljeđuju se u novu izvedenu klasu. Primjer sa odgovarajućom vizualizacijom dat je u nastavku.

class Base:
    pass

class Derived1(Base):
    pass

class Derived2(Derived1):
    pass



Redosljed rješavanja metoda u Pythonu

Svaka klasa u Pythonu izvedena je iz objektne klase. To je najosnovniji tip u Pythonu. Dakle, tehnički su sve ostale klase, bilo ugrađene ili korisnički definisane, izvedene klase i svi su objekti instance klase objekata.

# Ispisuje: True
print(issubclass(list,object))

# Ispisuje: True
print(isinstance(5.5,object))

# Ispisuje: True
print(isinstance("Hello",object))

U scenariju višestrukog nasljeđivanja, bilo koji navedeni atribut traži se prvo u trenutnoj klasi. Ako nije pronađena, pretraga se nastavlja u roditeljske klase po dubini, lijevo-desno bez dva pretraživanja iste klase. Dakle, u gornjem primjeru klase MultiDerived redosljed pretraživanja je [MultiDerived, Base1, Base2, object]. Ovaj se poredak naziva i linearizacija klase MultiDerived, a skup pravila koji se koriste za pronalaženje ovog naloga naziva se Method Resolution Order (MRO).

OSP mora spriječiti naručivanje lokalnog prioriteta i takođe osigurati monotonost. Osigurava da se klasa uvijek pojavi pred roditeljima. U slučaju više roditelja, redosljed je isti kao tuple osnovnih klasa. MRO klase može se gledati kao atribut __mro__ ili kao metoda mro(). Prva vraća tuple, dok druga vraća list (listu).

>>> MultiDerived.__mro__
(<class '__main__.MultiDerived'>,
 <class '__main__.Base1'>,
 <class '__main__.Base2'>,
 <class 'object'>)

>>> MultiDerived.mro()
[<class '__main__.MultiDerived'>,
 <class '__main__.Base1'>,
 <class '__main__.Base2'>,
 <class 'object'>]

Evo malo složenijeg primjera višestrukog nasljeđivanja i njegove vizualizacije zajedno s MRO.




# Demonstracija MRO

class X:
    pass

class Y:
    pass

class Z:
    pass

class A(X, Y):
    pass

class B(Y, Z):
    pass

class M(B, A, Z):
    pass

# Ispisuje:
# [<class '__main__.M'>, <class '__main__.B'>,
#  <class '__main__.A'>, <class '__main__.X'>,
#  <class '__main__.Y'>, <class '__main__.Z'>,
#  <class 'object'>]

print(M.mro())