
L'ereditarietà delle classi in Python
L'ereditarietà delle classi è un concetto fondamentale nella programmazione orientata agli oggetti (OOP) che permette a una classe, detta classe derivata o sottoclasse, di ereditare attributi e metodi da un'altra classe detta classe base o superclasse.
A cosa serve? L'ereditarietà ti permette di riutilizzare il codice che hai già scritto. Quindi, riduce la necessità di riscrivere il codice, rendendo più semplice la manutenzione e l'estensione delle funzionalità. Inoltre, rende la struttura del codice più organizzata e modulare.
Per comprendere meglio come funziona l'ereditarietà, consideriamo un esempio pratico in Python.
Supponi di avere una classe `Animal` che rappresenta un animale generico con un nome e un metodo per emettere un suono:
class Animal:
def __init__(self, name: str):
self.name = name
def sound(self):
return "Some generic sound"
Ora, crea una classe `Dog` che rappresenta un cane.
Invece di ridefinire tutto da capo, puoi fare in modo che `Dog` erediti da `Animal` e aggiungere il proprio metodo `sound` specifico:
class Dog(Animal):
def sound(self):
return "Bau"
In questo esempio, la classe `Dog` eredita l'attributo `name` dalla classe `Animal`. Inoltre, sovrascrive il metodo `sound` per restituire un suono specifico del cane.
In questo modo non hai dovuto ridefinirli nuovamente.
A questo punto crea un'istanza della classe Dog
dog = Dog("Buddy")
Se interroghi l'attributo "name" dell'oggetto ottieni il nome che gli hai assegnato.
print(dog.name)
Buddy
Se chiami il metodo sound() ottieni il verso del cane
print(dog.sound())
Bau
Per rendere l'esempio ancora più chiaro, aggiungi una seconda classe derivata, `Cat`, che rappresenta un gatto:
class Cat(Animal):
def sound(self):
return "Meow"
In questo caso hai creato una classe `Cat` che eredita da `Animal` e sovrascrive il metodo `sound` per restituire un suono specifico del gatto.
Ad esempio, crea un'istanza della classe Cat
cat = Cat("Whiskers")
Poi chiama il metodo sound() dell'oggetto
print(cat.sound())
Meow
Questo esempio semplice dimostra come l'ereditarietà consenta di riutilizzare e estendere il codice in modo efficace.
Puoi usare le classi anche per definite gli attributi di altre classi
Ecco un esempio in cui un attributo di una classe viene definito utilizzando un'altra classe esterna.
Questo esempio dimostra la composizione degli oggetti, un altro importante concetto della programmazione orientata agli oggetti.
Supponi di avere una classe `Address` che rappresenta un indirizzo:
class Address:
def __init__(self, street: str, city: str, zipcode: str):
self.street = street
self.city = city
self.zipcode = zipcode
def __str__(self):
return f"{self.street}, {self.city}, {self.zipcode}"
Poi crea una classe `Person` che utilizza `Address` come uno dei suoi attributi:
class Person:
def __init__(self, name: str, surname: str, address: Address):
self.name = name
self.surname = surname
self.address = address
def __str__(self):
return f"{self.name} {self.surname}, Address: {self.address}"
Ora crea un'istanza di `Address` e usarla per creare un'istanza di `Person`:
home_address = Address("123 Main St", "Springfield", "12345")
A questo punto crea un'istanza della classe Person utilizzando l'istanza di Address
person = Person("John", "Doe", home_address)
Se ora interroghi gli attributi dell'oggetto, vedrai che ha ereditato la struttura degli inidirizzi:
print(person)
John Doe, Address: 123 Main St, Springfield, 12345
In questo esempio, la classe `Person` ha un attributo `address` che è un'istanza della classe `Address`.
Questo mostra come una classe può utilizzare un'altra classe come parte della sua definizione, promuovendo la modularità e il riutilizzo del codice.