Object Oriented Programming (OOP) e Classi in Python

Introduzione

Questo notebook si basa sulle lezioni 8 e 9 di: https://ocw.mit.edu/courses/electrical-engineering-and-computer-science/6-0001-introduction-to-computer-science-and-programming-in-python-fall-2016/

Python contiene molti tipi di dati:

Ciascuno è un oggetto, caratterizzato da

In Python TUTTO È UN OGGETTO

OOP permette di separare la rappresentzione interna dall'interfaccia attraverso cui interagire con gli oggetti e dai dettagli delle manipolazioni a cui gli oggetti possono essere soggetti: dato un esemplare di oggetto automobile una delle sue caratteristiche è la velocità. Per ottenere che l'esemplare aumenti la sua velocità devo devo applicare la procedura aumentare la pressione sul pedale dell'acceleratore. Tutti gli esemplari di oggetto automobile aumentano la propria velocità usando la stessa procedura. Non ho bisogna di conoscere i dettagli di come un aumento della pressione sull'acceleratore porta al risultato di aumentare la velocità. Un eventuale miglioramento dei meccanismi interni non richiede una modifica dell'interfaccia pedale dell'acceleratore e quindi del modo con cui l'utilizzatore interagisce con l'esemplare.

Bisogna distinguere chiaramente fra creare una classe e utilizzare un esemplare di una classe:

Creare una classe

Utilizzare esemplari della classe

Aggiungiamo alla classe Coordinate un metodo per calcolare la distanza fra due punti. Uno dei due punti viene identificato con self in modo da poter chiamare il metodo su un singolo punto.
A parte l'uso di self e della notazione . per la chiamata, i metodi interni ad una classe si comportano esattamente come funzioni: prendono input, eseguono operazioni, restituiscono risultati.

Come usare i metodi di una classe

Stampare un esemplare di una classe e metodo __str__

Il comportamento di default di print su un membro di una classe non è molto utile. Può essere modificato definendo il metodo speciale str. Supponiamo di volere che print(c) restituisca <3,4>. Possiamo fare così:

Esistono molti altri metodi speciali. Per esempio:

__add__(self, other) --> self + other
__sub__(self, other) --> self - other
__eq__(self, other) --> self == other
__lt__(self, other) --> self < other
__len__(self) --> len(self)

Ciascuno di questi metodi può essere ridefinito come abbiamo fatto per __str__.

Un esempio piú elaborato

Definiamo una classe Fraction che rappresenti una frazione come una coppia numeratore-denominatore e permetta di eseguire le operazioni fra frazioni in modo esatto, senza trasformarle in floating point.

Alcuni esempi di utilizzo della classe Fraction.

Accedere a modificare i dati di un esemplare: getters and setters

Abbiamo visto che se nell\' __init__ di una classe C è definito l'attributo x è possibile accedere al valore dell'attributo per un esemplare es con la notazione es.x.
È però preferibile e fortemente incoraggiato accedere e modificare, dall'esterno della classe, gli attributi di un esemplare attraverso metodi appositi, detti getters e setters, che devono essere definiti all'interno della classe.

Una delle idee basilari dell'Object Oriented programmi è di interagire con gli oggetti solamente attraverso le funzioni della classe, nascondendo i dettagli interni dell'implementazione.

Inheritance

Una classe può ereditare metodi e attributi da una superclasse già esistente.

Dalla (super)classe Animal possiamo costruire sottoclassi che possiedono metodi e attributi particolari.

Esempio 1:

Una sottoclasse con due metodi addizionali e una implementazione diversa del metodo __str__:

Tutti i metodi di Animal sono applicabili a una instance di Cat:

Metodi nuovi o modificati

Esempio 2:

Una sottoclasse con metodi e attributi addizionali:

Una Person non può fare le fusa:

Esempio 3:

Una sottoclasse che eredita da un'altra sottoclasse con metodi e attributi addizionali e/o modificati

Uno Student, essendo una Person, può avere amici:

Ha una raffinata capacità di conversazione:

Esempio 4:

Una sottoclasse che possiede un attributo condiviso con tutti gli esemplari della classe