CodeGym /Corso Java /Python SELF IT /Ereditarietà multipla

Ereditarietà multipla

Python SELF IT
Livello 16 , Lezione 4
Disponibile

10.1 Ereditarietà da più classi

Ereditarietà multipla in Python permette a una classe di ereditare attributi e metodi da più di una classe genitore. Questo offre maggiore flessibilità e permette di riutilizzare il codice, ma può anche portare a gerarchie complesse e potenziali conflitti.

La possibilità di elencare alla tua classe cinque genitori amplia considerevolmente le tue possibilità e rende la scrittura del codice molto conveniente. Farlo è molto semplice — basta elencare le classi genitore separandole con una virgola:


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()     
        

Tutto funziona come previsto — fantastico.

Tuttavia, l'ereditarietà multipla ha alcuni aspetti complessi che devi considerare quando la usi. Vediamo come funziona e come evitare i problemi legati all'ereditarietà multipla.

10.2 Chiamata di un metodo presente in più classi base

Una classe può ereditare attributi e metodi da più classi genitore, elencate tra parentesi dopo il nome della classe. E questi attributi e metodi possono avere nomi uguali:


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() # quale metodo verrà chiamato?
        

In questo esempio, la classe Derived eredita da Base1 e Base2. Quando viene chiamato method(), Python sceglierà il metodo dalla prima classe indicata — Base1.

Ma non è così ovvio, vero? E se qualcuno modifica il codice della classe base, tutta la logica dell'applicazione potrebbe risentirne, e nemmeno saprai che qualcosa non va. Inizieranno semplicemente a chiamarsi metodi leggermente diversi :)

10.3 Uso di super() con ereditarietà multipla

Un'altra caratteristica interessante è la chiamata a super() per la classe base durante l'ereditarietà multipla.

Esempio:


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()
        

Allora? Quale sarà l'output?

Method from Derived
Method from Base1

Oppure

Method from Derived
Method from Base2 

Ho una sorpresa per te — l'output sarà:

Method from Derived
Method from Base1
Method from Base2

Il codice super().method() chiamerà il metodo method() di ciascuna classe base! Questo è proprio uno di quei dettagli di cui parlavo la prima volta che ho menzionato l'ereditarietà multipla.

10.4 Ereditarietà a rombo (Diamond)

E infine, il classico problema dell'ereditarietà a rombo. È più facile da mostrare con un esempio che da descrivere:

In codice può sembrare così, ad esempio:


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()
        

L'output sarà:

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

Per orientarti almeno un po' nell'ereditarietà multipla, devi sapere bene in quale ordine Python cerca i campi e i metodi delle classi genitore. Questo è proprio ciò che scoprirai nella prossima lezione.

Commenti
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION