Capitolo 11: Programmazione Orientata agli Oggetti

Impara a definire classi, creare oggetti, gestire ereditarietà e usare i metodi speciali di Python.

Scarica chapter11.py

Obiettivi

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

  1. Definisci una classe Rectangle con width, height e un metodo area().
  2. Implementa una classe base Vehicle e le sottoclassi Car, Bike sovrascrivendo il metodo move().
  3. Crea una classe Vector che supporti +, -, * tramite __add__, __sub__, __mul__.
  4. Usa @property per creare una proprietà di sola lettura full_name da first_name e last_name.