Capitolo 11: Programmazione Orientata agli Oggetti
Impara a definire classi, creare oggetti, gestire ereditarietà e usare i metodi speciali di Python.
Scaricachapter11.py
Obiettivi
- Definire classi e istanziare oggetti.
- Usare metodi e attributi di istanza, e il costruttore
__init__. - Lavorare con variabili di classe,
classmethodestaticmethod. - Implementare ereditarietà, overriding dei metodi e polimorfismo.
- Utilizzare metodi speciali (“dunder”) per personalizzare il comportamento.
- Incapsulare dati con attributi privati e
@property.
1. Classi & Istanze
Definisci una classe e il suo costruttore __init__:
class Person:
def __init__(self, name, age):
self.name = name # attributo di istanza
self.age = age
# Istanziare
alice = Person("Alice", 30)
print(alice.name, alice.age) # Alice 30
2. Membri di istanza & di classe
I metodi di istanza operano su self; le variabili di classe sono condivise:
class Counter:
total = 0 # variabile di classe
def __init__(self):
Counter.total += 1
self.id = Counter.total
def greet(self):
return f"Istanza {self.id} dice ciao"
# Utilizzo
c1 = Counter(); c2 = Counter()
print(c1.greet(), c2.greet())
print("Totale istanze:", Counter.total)
3. Ereditarietà & Polimorfismo
Sottoclassa per estendere o sovrascrivere comportamenti:
class Animal:
def speak(self):
raise NotImplementedError
class Dog(Animal):
def speak(self):
return "Woof!"
class Cat(Animal):
def speak(self):
return "Meow!"
for pet in (Dog(), Cat()):
print(pet.speak()) # Woof! Meow!
4. Metodi Speciali
Implementa __str__, __repr__, __eq__ per comportamenti avanzati:
class Point:
def __init__(self, x, y):
self.x, self.y = x, y
def __repr__(self):
return f"Point({self.x},{self.y})"
def __eq__(self, other):
return isinstance(other, Point) and (self.x, self.y)==(other.x, other.y)
p1, p2 = Point(1,2), Point(1,2)
print(p1, p2, p1==p2) # Point(1,2) Point(1,2) True
5. Incapsulamento & @property
Usa il name mangling per attributi “privati” e @property per getter/setter:
class Account:
def __init__(self, bal):
self.__balance = bal
@property
def balance(self):
return self.__balance
@balance.setter
def balance(self, val):
if val < 0:
raise ValueError("Saldo negativo")
self.__balance = val
acct = Account(100)
print(acct.balance) # 100
acct.balance = 150
# acct.balance = -50 # ValueError
Esercizi
- Definisci una classe
Rectangleconwidth,heighte un metodoarea(). - Implementa una classe base
Vehiclee le sottoclassiCar,Bikesovrascrivendo il metodomove(). - Crea una classe
Vectorche supporti +, -, * tramite__add__,__sub__,__mul__. - Usa
@propertyper creare una proprietà di sola letturafull_namedafirst_nameelast_name.