Classi definite dall’Utente

Abbiamo già visto classi come str, int, float e Turtle definite da Python. Tuttavia, in molti casi abbiamo bisogno di creare oggetti che si relazionano al problema che stiamo cercando di risolvere. In questo caso, abbiamo bisogno di creare le nostre classi.

Ad esempio, consideriamo il concetto matematico di punto. In due dimensioni, un punto è dato da due numeri (coordinate) che sono trattare collettivamente come un singolo oggetto. I punti sono spesso scritti scrivendo le coordinate tra parentesi separate da una virgola. Per esempio, (0, 0) rappresenta l’origine, e (x, y) rappresenta x unità a destra e y unità sopra l’origine. Questo (x,y) è lo stato del punto.

Pensando al nostro diagramma sopra, potremmo disegnare un oggetto point come mostrato qui.

Un punto ha una x e una y

Alcune delle operazioni tipiche che possiamo associare ai punti sono dei metodi per avere accesso alle sue coordinate, del tipo getX o getY per richiedere rispettivamente la x e la y del punto. Potremmo volere anche chiedere la distanza di un punto dall’origine, o la distanza di un punto da un altro punto, o di trovare il punto di mezzo tra due punti, o se il punto cade all’interno di un dato rettangolo o cerchio. Vedremo brevemente come organizzare tutto ciò.

Un punto ha anche dei metodi

Adesso che abbiamo capito come un oggetto point deve essere, possiamo definire una nuova classe. Vorremmo che i nostri punti abbiano un attributo x e un attributo y, per cui la definizione della classe è la seguente.

1
2
3
4
5
6
7
class Point:
    """ Point class for representing and manipulating x,y coordinates. """

    def __init__(self):
        """ Create a new point at the origin """
        self.x = 0
        self.y = 0

Le definizioni delle classi possono apparire ovunque in un programma, ma sono di solito dopo le istruzioni import. La sintassi per le cassi simile a quella per la definizione di istruzioni composte. C’è una intestazione che comincia con la parola chiave class seguita dal nome della classe e i due punti.

Ogni classe deve avere un metodo speciale con nome __init__. Questo metodo di inizializzazione, spesso riferito con il nome di costruttore, viene automaticamente chiamato qualora una nuova istanza di Point viene creata. La sua funzione è quella di inizializzare gli attributi. Il parametro self (potrebbe chiamarsi in altro modo, ma viene usato per convenzione) è automaticamente posto uguale al riferimento dell’oggetto appena creato che necessita di essere inizializzato.




(chp13_classes1)

Durante l’inizializzazione degli oggetti, abbiamo creato due attributi chiamati x e y per ciascuno inizializzandoli a 0. Sembra che non sia successo niente, ma non è vero, ma è solo perché non abbiamo chiesto ai punti di fare niente, per cui non vediamo risultati.

Oggetti semplici hanno uno stato e dei metodi.

(chp13_points)

Il programma seguente aggiunge alcune istruzioni di stampa. L’operatore is ritorna False perché si tratta di due oggetti diversi.




(chp13_classes2)

Questo sembra familiare, visto che lo abbiamo usato quando abbiamo creato le tartarughe:

from turtle import Turtle

tess = Turtle()     # Instantiate objects of type Turtle
alex = Turtle()

Le variabili p e q sono contengono riferimenti a due nuovi oggetti Point. Le funzioni Turtle e Point che creano oggetti sono chiamati construttori. Ogni classe automaticamente usa il nome della classe come nome per il suo costruttore. La definizione del costruttore è fatta quando definiamo la funzione __init__.

E’ utile pensare a una classe come ad una fabbrica di oggetti. La classe non è un oggetto ma contiene la tecnica per creare oggetti. Ogni volta che chiamiamo il costruttore, stiamo chiedendo alla fabbrica di creare un nuovo oggetto. Il processo di creazione di un oggetto e di inizializzazione è chiamato instanziazione.

Next Section - Migliorare il Costruttore