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,
classmethod
estaticmethod
. - 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
Rectangle
conwidth
,height
e un metodoarea()
. - Implementa una classe base
Vehicle
e le sottoclassiCar
,Bike
sovrascrivendo il metodomove()
. - Crea una classe
Vector
che supporti +, -, * tramite__add__
,__sub__
,__mul__
. - Usa
@property
per creare una proprietà di sola letturafull_name
dafirst_name
elast_name
.