Man mano che i programmi crescono in dimensioni e complessità, gestire e organizzare il codice può diventare piuttosto impegnativo. Funzioni e variabili potrebbero essere sparse in diverse parti di un programma, rendendo difficile tenere traccia di ciò che sta accadendo e portando a codice disordinato e difficile da mantenere. È qui che entrano in gioco le classi, una pietra angolare della programmazione orientata agli oggetti.
💡
Le classi sono un modo per raggruppare dati e funzioni correlati, creando ciò che chiamiamo 'oggetti'.
Le classi sono i concetti fondamentali nella programmazione orientata agli oggetti (OOP).
Le classi sono come progetti per creare oggetti nel nostro codice. Ogni classe racchiude proprietà (dati) e metodi (funzioni) correlati in unità singole. Ad esempio, in un programma di gioco, potresti avere classi come Player, Monster o Item, ognuna contenente i propri dati e metodi pertinenti. Questo rende più facile comprendere e gestire grandi basi di codice, poiché le funzionalità correlate sono raggruppate ed è chiaro come interagiscono tra loro.
Supponiamo che tu voglia creare un software per modellare una biblioteca. Potresti avere libri nella tua biblioteca, quindi dovrai creare una classe Book:
class Book:
def __init__(self, title, author, pages):
self.title = title # Assegna il titolo all'istanza del libro
self.author = author # Assegna l'autore all'istanza del libro
self.pages = pages # Assegna il numero di pagine all'istanza del libro
La parola chiave class introduce una nuova classe, seguita dal suo nome (Book). La linea def __init__(self, title, author, pages): definisce lo stato iniziale della classe o il costruttore. È qui che l'oggetto viene inizializzato. self si riferisce all'istanza della classe. title, author e pages sono attributi della classe.
Puoi creare un nuovo oggetto libro chiamando la classe come una funzione:
# Crea una nuova istanza di Book
mockingbird = Book('To Kill a Mockingbird', 'Harper Lee', 281)
print(mockingbird.title) # To Kill a Mockingbird
print(mockingbird.author) # Harper Lee
print(mockingbird.pages) # 281
Nota che passiamo To Kill a Mockingbird, Harper Lee e 281 come argomenti. Questi vengono passati come argomenti al metodo __init__ (quasi come una normale funzione).
Possiamo creare diverse istanze della classe Book:
# Crea altre istanze di libri
book2 = Book('1984', 'George Orwell', 328)
book3 = Book('The Great Gatsby', author='F. Scott Fitzgerald', pages=180)
book4 = Book('Moby Dick', 'Herman Melville', pages=720)
# Stampa alcune informazioni sui libri
print(f'{book2.title} by {book2.author} has {book2.pages} pages.') # 1984 di George Orwell ha 328 pagine.
print(f'{book3.title} by {book3.author} has {book3.pages} pages.') # The Great Gatsby di F. Scott Fitzgerald ha 180 pagine.
print(f'{book4.title} by {book4.author} has {book4.pages} pages.') # Moby Dick di Herman Melville ha 720 pagine.
Proprio come con le funzioni, possiamo passare sia argomenti posizionali che argomenti con parole chiave al metodo __init__.
Oltre ai dati, le classi possono anche incapsulare funzionalità. Supponiamo che, nel nostro sistema di biblioteca, vogliamo contrassegnare un libro come letto. Possiamo definire un metodo nella nostra classe Book a questo scopo:
class Book:
def __init__(self, title, author, pages):
self.title = title # Assegna il titolo all'istanza del libro
self.author = author # Assegna l'autore all'istanza del libro
self.pages = pages # Assegna il numero di pagine all'istanza del libro
self.is_read = False # Il libro non è ancora stato letto
def mark_as_read(self): # Un metodo della classe
self.is_read = True # Contrassegna il libro come letto
mockingbird = Book('To Kill a Mockingbird', 'Harper Lee', 281)
print(mockingbird.is_read) # False, il libro non è ancora stato letto
mockingbird.mark_as_read() # Contrassegna il libro come letto
print(mockingbird.is_read) # True, il libro è stato letto
Il metodo mark_as_read cambia lo stato dell'attributo is_read a True. Possiamo chiamare questo metodo su qualsiasi istanza di libro. Questo dimostra come possiamo raggruppare dati e funzionalità correlati usando le classi in Python.
💡
In Python, self è un nome convenzionale per il primo parametro nei metodi di istanza di una classe. È un riferimento all'istanza corrente della classe. self viene utilizzato per accedere agli attributi e ai metodi della classe all'interno della sua definizione.
Quando crei un nuovo oggetto della classe, Python associa automaticamente l'argomento self a quel nuovo oggetto, ed è per questo che non passi self quando chiami un metodo di istanza.
Anche se self non è una parola chiave riservata in Python, è ampiamente utilizzato per lo stile chiaro e leggibile che incoraggia. È importante notare che potresti usare qualsiasi altro nome, ma l'uso di self è fortemente raccomandato dalla comunità ed è considerato una buona pratica.
Sfida: Crea una Classe Car
Ti viene richiesto di creare una classe Car che abbia i seguenti attributi:
color (il colore dell'auto)
make (la marca dell'auto)
model (lo specifico modello dell'auto)
year (l'anno in cui è stata prodotta)
Questi attributi dovrebbero essere inizializzati nel metodo __init__ della classe.
Inoltre, la classe Car dovrebbe avere un metodo display_details. Questo metodo dovrebbe restituire una rappresentazione in forma di stringa dei dettagli dell'auto nel formato [year] [color] [make] [model].
Input
Output
ㅤ
c = Car('red', 'Ferrari', 'F8', 2023); print(c.display_details())
2023 red Ferrari F8
ㅤ
c = Car('black', 'Tesla', 'Model S', 2021); print(c.display_details())