Ereditarietà in Python

Uno dei concetti fondamentali in programmazione orientata agli oggetti (OOP) è un'eredità. È un meccanismo che consente di creare una gerarchia di classi che condividono un insieme di proprietà e metodi derivando una classe da un'altra classe. L'ereditarietà è la capacità di una classe di derivare o ereditare le proprietà da un'altra classe.

I vantaggi dell'eredità sono:

L'ereditarietà consente di ereditare le proprietà di una classe, ovvero la classe base, di un'altra, ovvero la classe derivata. I vantaggi dell'ereditarietà in Python sono i seguenti:

  • Rappresenta bene le relazioni del mondo reale.
  • Fornisce il riusabilità di un codice. Non dobbiamo scrivere lo stesso codice ancora e ancora. Inoltre, ci consente di aggiungere più funzionalità a una classe senza modificarla.
  • È di natura transitiva, il che significa che se la classe B eredita da un'altra classe A, allora tutte le sottoclassi di B erediteranno automaticamente dalla classe A.
  • L'ereditarietà offre una struttura del modello semplice e comprensibile.
  • Meno spese di sviluppo e manutenzione derivano da un'eredità.

Sintassi dell'ereditarietà Python

La sintassi dell'ereditarietà semplice in Python è la seguente:

Class BaseClass: {Body} Class DerivedClass(BaseClass): {Body} 

Creazione di una classe genitore

Una classe genitore è una classe le cui proprietà sono ereditate dalla classe figlia. Creiamo una classe genitore chiamata Persona che ha a Schermo metodo per visualizzare le informazioni della persona.

Python3




# A Python program to demonstrate inheritance> class> Person(> object> ):> > > # Constructor> > def> __init__(> self> , name,> id> ):> > self> .name> => name> > self> .> id> => id> > # To check if this person is an employee> > def> Display(> self> ):> > print> (> self> .name,> self> .> id> )> # Driver code> emp> => Person(> 'Satyam'> ,> 102> )> # An Object of Person> emp.Display()>

Produzione:

Satyam 102 

Creazione di una classe figlia

Una classe figlia è una classe che guida le proprietà dalla sua classe genitore. Qui Imp è un'altra classe che erediterà le proprietà di Persona classe(classe base).

Python3




class> Emp(Person):> > > def> Print> (> self> ):> > print> (> 'Emp class called'> )> > Emp_details> => Emp(> 'Mayank'> ,> 103> )> # calling parent class function> Emp_details.Display()> # Calling child class function> Emp_details.> Print> ()>

Produzione:

Mayank 103 Emp class called 

Esempio di ereditarietà in Python

Vediamo un esempio di semplice ereditarietà Python in cui una classe figlia eredita le proprietà della sua classe genitore. In questo esempio, 'Person' è la classe genitore e 'Employee' è la classe figlia.

Python3




# A Python program to demonstrate inheritance> # Base or Super class. Note object in bracket.> # (Generally, object is made ancestor of all classes)> # In Python 3.x 'class Person' is> # equivalent to 'class Person(object)'> class> Person(> object> ):> > # Constructor> > def> __init__(> self> , name):> > self> .name> => name> > # To get name> > def> getName(> self> ):> > return> self> .name> > # To check if this person is an employee> > def> isEmployee(> self> ):> > return> False> # Inherited or Subclass (Note Person in bracket)> class> Employee(Person):> > # Here we return true> > def> isEmployee(> self> ):> > return> True> # Driver code> emp> => Person(> 'Geek1'> )> # An Object of Person> print> (emp.getName(), emp.isEmployee())> emp> => Employee(> 'Geek2'> )> # An Object of Employee> print> (emp.getName(), emp.isEmployee())>

Produzione:

Geek1 False Geek2 True 

Cos'è una classe di oggetti in Python?

Come il Classe oggetto Java , in Python (dalla versione 3. x), l'oggetto è la radice di tutte le classi.

  • In Python 3.x, la classe Test(oggetto) e la classe Test sono la stessa cosa.
  • In Python 2. x, la classe Test(oggetto) crea una classe con l'oggetto come genitore (chiamata classe di nuovo stile) e la classe Test crea una classe vecchio stile (senza un genitore che si oppone).

Sottoclasse (chiamata al costruttore della classe genitore)

Una classe figlia deve identificare quale classe è la sua classe genitore. Questo può essere fatto menzionando il nome della classe genitore nella definizione della classe figlia.

Esempio: nome_sottoclasse della classe (nome_superclasse)

In questo esempio, 'UN' è l'istanza creata per la classe Persona. Richiama __init__() della classe a cui si fa riferimento. Puoi vedere 'oggetto' scritto nella dichiarazione della classe Persona. In Python, ogni classe eredita da una classe di base incorporata chiamata 'oggetto'. Il costruttore, ovvero la funzione '__init__' di una classe, viene invocato quando creiamo una variabile oggetto o un'istanza della classe.

Le variabili definite all'interno di __init__() sono chiamate variabili di istanza o oggetti. Pertanto, 'nome' e 'idnumero' sono gli oggetti della classe Persona. Allo stesso modo, 'stipendio' e 'posta' sono gli oggetti della classe Impiegato. Poiché la classe Employee eredita dalla classe Person, anche ‘name’ e ‘idnumber’ sono oggetti della classe Employee.

Python3




# Python code to demonstrate how parent constructors> # are called.> # parent class> class> Person(> object> ):> > # __init__ is known as the constructor> > def> __init__(> self> , name, idnumber):> > self> .name> => name> > self> .idnumber> => idnumber> > def> display(> self> ):> > print> (> self> .name)> > print> (> self> .idnumber)> # child class> class> Employee(Person):> > def> __init__(> self> , name, idnumber, salary, post):> > self> .salary> => salary> > self> .post> => post> > # invoking the __init__ of the parent class> > Person.__init__(> self> , name, idnumber)> # creation of an object variable or an instance> a> => Employee(> 'Rahul'> ,> 886012> ,> 200000> ,> 'Intern'> )> # calling a function of the class Person using its instance> a.display()>

Produzione:

Rahul 886012 

Programma Python per dimostrare l'errore se dimentichiamo di invocare __init__() del genitore

Se dimentichi di invocare __init__() della classe genitore, le sue variabili di istanza non saranno disponibili per la classe figlia. Il codice seguente produce un errore per lo stesso motivo.

Python3




class> A:> > def> __init__(> self> , n> => 'Rahul'> ):> > self> .name> => n> class> B(A):> > def> __init__(> self> , roll):> > self> .roll> => roll> object> => B(> 23> )> print> (> object> .name)>

Produzione :

Traceback (most recent call last): File '/home/de4570cca20263ac2c4149f435dba22c.py', line 12, in print (object.name) AttributeError: 'B' object has no attribute 'name' 

La funzione super()

IL funzione super() è una funzione incorporata che restituisce gli oggetti che rappresentano la classe genitore. Permette di accedere ai metodi e agli attributi della classe genitore nella classe figlia.

Esempio: funzione super() con semplice ereditarietà Python

In questo esempio, abbiamo creato l'oggetto 'obj' della classe figlia. Quando abbiamo chiamato il costruttore della classe figlia 'Student', ha inizializzato i membri dati sui valori passati durante la creazione dell'oggetto. Quindi, utilizzando la funzione super(), abbiamo invocato il costruttore della classe genitore.

Python3




# parent class> class> Person():> > def> __init__(> self> , name, age):> > self> .name> => name> > self> .age> => age> > def> display(> self> ):> > print> (> self> .name,> self> .age)> # child class> class> Student(Person):> > def> __init__(> self> , name, age):> > self> .sName> => name> > self> .sAge> => age> > # inheriting the properties of parent class> > super> ().__init__(> 'Rahul'> , age)> > def> displayInfo(> self> ):> > print> (> self> .sName,> self> .sAge)> obj> => Student(> 'Mayank'> ,> 23> )> obj.display()> obj.displayInfo()>

Produzione:

Rahul 23 Mayank 23 

Aggiunta di proprietà

Una delle funzionalità fornite dall'ereditarietà è quella di ereditare le proprietà della classe genitore e di aggiungere nuove proprietà alla classe figlia. Vediamolo con un esempio:

Python3




# parent class> class> Person():> > def> __init__(> self> , name, age):> > self> .name> => name> > self> .age> => age> > def> display(> self> ):> > print> (> self> .name,> self> .age)> # child class> class> Student(Person):> > def> __init__(> self> , name, age, dob):> > self> .sName> => name> > self> .sAge> => age> > self> .dob> => dob> > # inheriting the properties of parent class> > super> ().__init__(> 'Rahul'> , age)> > def> displayInfo(> self> ):> > print> (> self> .sName,> self> .sAge,> self> .dob)> obj> => Student(> 'Mayank'> ,> 23> ,> '16-03-2000'> )> obj.display()> obj.displayInfo()>

Produzione:

Qui possiamo vedere che abbiamo aggiunto una nuova proprietà alla classe figlia, ovvero la data di nascita (dob).

Rahul 23 Mayank 23 16-03-2000 

Diversi tipi di eredità Python

Esistono 5 diversi tipi di ereditarietà in Python. Sono i seguenti:

    Ereditarietà singola: quando una classe figlia eredita da una sola classe genitore, si parla di ereditarietà singola. Abbiamo visto un esempio sopra. Eredità multiple: quando una classe figlia eredita da più classi genitori, si parla di eredità multiple.

A differenza di Java, Python mostra più eredità.

Python3




# Python example to show the working of multiple> # inheritance> class> Base1(> object> ):> > def> __init__(> self> ):> > self> .str1> => 'Geek1'> > print> (> 'Base1'> )> class> Base2(> object> ):> > def> __init__(> self> ):> > self> .str2> => 'Geek2'> > print> (> 'Base2'> )> class> Derived(Base1, Base2):> > def> __init__(> self> ):> > # Calling constructors of Base1> > # and Base2 classes> > Base1.__init__(> self> )> > Base2.__init__(> self> )> > print> (> 'Derived'> )> > def> printStrs(> self> ):> > print> (> self> .str1,> self> .str2)> ob> => Derived()> ob.printStrs()>

Produzione:

Base1 Base2 Derived Geek1 Geek2 
    Eredità multilivello: quando abbiamo una relazione figlio e nipote. Ciò significa che una classe figlia erediterà dalla sua classe genitore, che a sua volta erediterà dalla sua classe genitore.

Python3




# A Python program to demonstrate inheritance> # Base or Super class. Note object in bracket.> # (Generally, object is made ancestor of all classes)> # In Python 3.x 'class Person' is> # equivalent to 'class Person(object)'> class> Base(> object> ):> > # Constructor> > def> __init__(> self> , name):> > self> .name> => name> > # To get name> > def> getName(> self> ):> > return> self> .name> # Inherited or Sub class (Note Person in bracket)> class> Child(Base):> > # Constructor> > def> __init__(> self> , name, age):> > Base.__init__(> self> , name)> > self> .age> => age> > # To get name> > def> getAge(> self> ):> > return> self> .age> # Inherited or Sub class (Note Person in bracket)> class> GrandChild(Child):> > # Constructor> > def> __init__(> self> , name, age, address):> > Child.__init__(> self> , name, age)> > self> .address> => address> > # To get address> > def> getAddress(> self> ):> > return> self> .address> # Driver code> g> => GrandChild(> 'Geek1'> ,> 23> ,> 'Noida'> )> print> (g.getName(), g.getAge(), g.getAddress())>

Produzione:

Geek1 23 Noida 
    Ereditarietà gerarchica È possibile creare più classi derivate da un'unica base. Eredità ibrida: questa forma combina più di una forma di ereditarietà. Fondamentalmente, è una miscela di più di un tipo di eredità.

Per maggiori dettagli leggi questo articolo: Tipi di ereditarietà in Python

Membri privati ​​della classe genitore

Non vogliamo sempre che le variabili di istanza della classe genitore vengano ereditate dalla classe figlia, ovvero possiamo rendere private alcune variabili di istanza della classe genitore, che non saranno disponibili per la classe figlia.

Nell'ereditarietà Python, possiamo rendere privata una variabile di istanza aggiungendo doppi caratteri di sottolineatura prima del suo nome. Per esempio:

Python3




# Python program to demonstrate private members> # of the parent class> class> C(> object> ):> > def> __init__(> self> ):> > self> .c> => 21> > # d is private instance variable> > self> .__d> => 42> class> D(C):> > def> __init__(> self> ):> > self> .e> => 84> > C.__init__(> self> )> object1> => D()> # produces an error as d is private instance variable> print> (object1.c)> print> (object1.__d)>

Produzione :

Qui possiamo vedere che quando proviamo a stampare la variabile 'c', il suo valore 21 viene stampato sulla console. Mentre quando abbiamo provato a stampare 'd', ha generato l'errore. Questo perché la variabile 'd' viene resa privata utilizzando i caratteri di sottolineatura. Non è disponibile per la classe figlia 'D' e da qui l'errore.

21 File '/home/993bb61c3e76cda5bb67bd9ea05956a1.py', line 16, in print (object1.d) AttributeError: type object 'D' has no attribute 'd'