Tecnologie dell'Informazione e della Comunicazionegaspari/www/teaching/tic8.pdf · © Mauro Gaspari...

37
© Mauro Gaspari - University of Bologna - [email protected] Tecnologie dell'Informazione e della Comunicazione Capitolo 11 Classi e Oggetti Prof. Mauro Gaspari: [email protected]

Transcript of Tecnologie dell'Informazione e della Comunicazionegaspari/www/teaching/tic8.pdf · © Mauro Gaspari...

Page 1: Tecnologie dell'Informazione e della Comunicazionegaspari/www/teaching/tic8.pdf · © Mauro Gaspari - University of Bologna - gaspari@cs.unibo.it Tecnologie dell'Informazione e della

© Mauro Gaspari - University of Bologna - [email protected]

Tecnologie dell'Informazione e della Comunicazione

Capitolo 11Classi e Oggetti

Prof. Mauro Gaspari: [email protected]

Page 2: Tecnologie dell'Informazione e della Comunicazionegaspari/www/teaching/tic8.pdf · © Mauro Gaspari - University of Bologna - gaspari@cs.unibo.it Tecnologie dell'Informazione e della

© Mauro Gaspari - University of Bologna - [email protected]

Definire nuovi tipi?

● Abbiamo visto diversi tipi di dato strutturati:– stringhe

– liste

– tuple

– dizionari

● È possibile definirne dei nuovi, che magari siano specifici per particolari applicazioni?

Page 3: Tecnologie dell'Informazione e della Comunicazionegaspari/www/teaching/tic8.pdf · © Mauro Gaspari - University of Bologna - gaspari@cs.unibo.it Tecnologie dell'Informazione e della

© Mauro Gaspari - University of Bologna - [email protected]

Tipi di dato Astratti● Che caratteristiche hanno i tipi di dato visti fino ad ora:

– contengono informazioni (scalari/strutturate)

– ci sono un insieme di operazioni predefinite che sono le uniche che accedono all'implementazione del dato.

– l'utente non è a conoscenza di come sono realizzate internamente queste operazioni (sono incapsulate).

● Le operazioni si possono utilizzare con una certa tranquillità,

senza conoscere i dettagli di come sono realizzate (information

hiding).

● Un tipo di dato che ha queste proprietà si chiama tipo di dato

astratto (=abstract data type).

Page 4: Tecnologie dell'Informazione e della Comunicazionegaspari/www/teaching/tic8.pdf · © Mauro Gaspari - University of Bologna - gaspari@cs.unibo.it Tecnologie dell'Informazione e della

© Mauro Gaspari - University of Bologna - [email protected]

Tipi di dato definiti dall'utente

● Buoni tipi di dato definiti dall'utente dovrebbero avere le caratteristiche dei tipi di dato astratti.

● Ovvero:– implementazione nascosta.

– un insieme di procedure e funzioni che accedono al dato che sono le uniche che accedono al dato.

Page 5: Tecnologie dell'Informazione e della Comunicazionegaspari/www/teaching/tic8.pdf · © Mauro Gaspari - University of Bologna - gaspari@cs.unibo.it Tecnologie dell'Informazione e della

© Mauro Gaspari - University of Bologna - [email protected]

Un esempio: il punto

● Concetto di punto in matematica.

● In uno spazio bidimensionale un punto è rappresentato da due

numeri, le coordinate, che vengono trattate insieme come un

singolo oggetto.

● Esempio di notazione matematica:

– (0,0) origine

– (x,y) rappresenta un punto con coordinate x e y.

Page 6: Tecnologie dell'Informazione e della Comunicazionegaspari/www/teaching/tic8.pdf · © Mauro Gaspari - University of Bologna - gaspari@cs.unibo.it Tecnologie dell'Informazione e della

© Mauro Gaspari - University of Bologna - [email protected]

Come realizzare un punto in Python?

● Si potrebbe rappresentare con due numeri floating-point.

● Sarebbe però opportuno raggrupparli in un singolo oggetto.

– lista

– tupla

● Una soluzione può essere meglio dell'altra a seconda

dell'applicazione. Ad esempio se si vuole trovare dei punti che

possono essere modificati è meglio utilizzare le liste.

Page 7: Tecnologie dell'Informazione e della Comunicazionegaspari/www/teaching/tic8.pdf · © Mauro Gaspari - University of Bologna - gaspari@cs.unibo.it Tecnologie dell'Informazione e della

© Mauro Gaspari - University of Bologna - [email protected]

Esempio

● Realizzazione di un punto come lista.

● Definizione della funzione muovi, che sposta il punto.

>>> punto = [0,0]>>> def muovi(p,x,y)...   p[0] = x...   p[1] = y...>>> muovi(punto,4,5)>>> punto[4,5]

Page 8: Tecnologie dell'Informazione e della Comunicazionegaspari/www/teaching/tic8.pdf · © Mauro Gaspari - University of Bologna - gaspari@cs.unibo.it Tecnologie dell'Informazione e della

© Mauro Gaspari - University of Bologna - [email protected]

Osservazioni● Una volta scelta la rappresentazione si realizzano le operazioni

che operano sui punti, ad esempio la funzione muovi.

● Però il punto così definito non è un tipo di dato astratto, ovvero

non:

– Posso usare altre funzioni sul punto, ad esempio len.

– È facile definire altre operazioni che accedono alla struttura interna del punto.

– Posso addirittura modificare la struttura senza rendermene conto.

– Il tipo (type) non risulta essere punto ma lista.

Page 9: Tecnologie dell'Informazione e della Comunicazionegaspari/www/teaching/tic8.pdf · © Mauro Gaspari - University of Bologna - gaspari@cs.unibo.it Tecnologie dell'Informazione e della

© Mauro Gaspari - University of Bologna - [email protected]

Esempio

>>> len(punto)2>>> type(punto)<type 'list'>>>> punto[1:1] = [5,6]>>> punto[4, 5, 6, 5]>>>    

Page 10: Tecnologie dell'Informazione e della Comunicazionegaspari/www/teaching/tic8.pdf · © Mauro Gaspari - University of Bologna - gaspari@cs.unibo.it Tecnologie dell'Informazione e della

© Mauro Gaspari - University of Bologna - [email protected]

Le classi

● Python, come altri linguaggi di programmazione, fornisce dei

meccanismi ad alto livello per creare tipi di dato definiti

dall'utente che siano più vicini ai tipi predefiniti.

● Questi tipi si definiscono con il concetto di classe (= class).

class Point:  def __init__(self, x, y):    self.x = x    self.y = y

Page 11: Tecnologie dell'Informazione e della Comunicazionegaspari/www/teaching/tic8.pdf · © Mauro Gaspari - University of Bologna - gaspari@cs.unibo.it Tecnologie dell'Informazione e della

© Mauro Gaspari - University of Bologna - [email protected]

Le classi● Queste definizioni possono apparire in qualsiasi punto del

programma ma di solito è opportuno inserirle all'inizio dopo i

comandi import.

● Le regole sintattiche per definire le classi sono simili a quelle

degli altri tipi composti.

● La definizione crea una nuova classe. Quando si crea una classe

Point si crea anche un nuovo tipo chiamato Point.

● I membri di questa classe sono detti istanze del tipo creato oppure

oggetti.

Page 12: Tecnologie dell'Informazione e della Comunicazionegaspari/www/teaching/tic8.pdf · © Mauro Gaspari - University of Bologna - gaspari@cs.unibo.it Tecnologie dell'Informazione e della

© Mauro Gaspari - University of Bologna - [email protected]

La funzione __init__: un metodo.

● La funzione __init__ definisce come inizializzare i membri della

classe, si chiama anche metodo (= method) perché può essere

invocata solo sugli elementi della classe.

– la variabile self si riferisce all'oggetto che sto creando, per convenzione deve essere il primo argomento del metodo;

– la classe Point a due attributi x e y;

– le notazioni self.x e self.y indica gli attributi dell'oggetto (la notazione è simile a quella dei moduli).

Page 13: Tecnologie dell'Informazione e della Comunicazionegaspari/www/teaching/tic8.pdf · © Mauro Gaspari - University of Bologna - gaspari@cs.unibo.it Tecnologie dell'Informazione e della

© Mauro Gaspari - University of Bologna - [email protected]

Istanze o Oggetti

● Per creare le istanze della classe Point si usa una funzione

costruttore denominata Point, che invoca in modo trasparente la

funzione __init__

blank = Point(0,0)

Alla variabile blank vieneassegnato un riferimentoal nuovo oggetto.

Page 14: Tecnologie dell'Informazione e della Comunicazionegaspari/www/teaching/tic8.pdf · © Mauro Gaspari - University of Bologna - gaspari@cs.unibo.it Tecnologie dell'Informazione e della

© Mauro Gaspari - University of Bologna - [email protected]

Osservazioni

● La creazione di un oggetto si dice istanziazione.

● La funzione __init__ potrebbe non esserci. In tal caso si creano

oggetti senza attributi. Questi potrebbero essere aggiunti in

seguito.

● Per rendere più chiara la struttura dei programmi che contengono

nuovi tipi. Si consigli di utilizzare sempre la funzione __init__ e

di inserire tutti gli attributi di una classe in questa funzione.

Page 15: Tecnologie dell'Informazione e della Comunicazionegaspari/www/teaching/tic8.pdf · © Mauro Gaspari - University of Bologna - gaspari@cs.unibo.it Tecnologie dell'Informazione e della

© Mauro Gaspari - University of Bologna - [email protected]

Esempio

>>> blank.x0>>> blank.y0>>> blank<__main__.Point instance at 0xb7f75c2c>>>>>>> type(blank)<type 'instance'>>>>           

Page 16: Tecnologie dell'Informazione e della Comunicazionegaspari/www/teaching/tic8.pdf · © Mauro Gaspari - University of Bologna - gaspari@cs.unibo.it Tecnologie dell'Informazione e della

© Mauro Gaspari - University of Bologna - [email protected]

Esempio

● Posso modificare gli attributi di un oggetto:

>>> blank.x = 3.0>>> blank.y = 4.0

Page 17: Tecnologie dell'Informazione e della Comunicazionegaspari/www/teaching/tic8.pdf · © Mauro Gaspari - University of Bologna - gaspari@cs.unibo.it Tecnologie dell'Informazione e della

© Mauro Gaspari - University of Bologna - [email protected]

Esempio

>>> print blank.y4.0>>> x = blank.x>>> print x3.0

La notazione con il punto si usa anche per accedereagli attributi.

NB. non c'è conflitto tra lax variabile e quella nell'oggettoche è un attributo.

Page 18: Tecnologie dell'Informazione e della Comunicazionegaspari/www/teaching/tic8.pdf · © Mauro Gaspari - University of Bologna - gaspari@cs.unibo.it Tecnologie dell'Informazione e della

© Mauro Gaspari - University of Bologna - [email protected]

Stampare un oggetto

>>> blank<__main__.Point instance at 0xb7f75c2c>

# si stampa il riferimento in esadecimale

def printPoint(p):  print '(' + str(p.x) + ', ' + str(p.y) + ')'

NB. un oggetto può essere passato come parametro.Come nel caso delle liste si passa il riferimento.

Page 19: Tecnologie dell'Informazione e della Comunicazionegaspari/www/teaching/tic8.pdf · © Mauro Gaspari - University of Bologna - gaspari@cs.unibo.it Tecnologie dell'Informazione e della

© Mauro Gaspari - University of Bologna - [email protected]

Valori di default

● Alle funzioni è possibile dare valori di default.

● Lo stesso si può fare con i metodi.

def stampaSempre(x=0):...   print x...>>> stampaSempre(1)1>>> stampaSempre()0

Page 20: Tecnologie dell'Informazione e della Comunicazionegaspari/www/teaching/tic8.pdf · © Mauro Gaspari - University of Bologna - gaspari@cs.unibo.it Tecnologie dell'Informazione e della

© Mauro Gaspari - University of Bologna - [email protected]

Esempi

def find(str, ch):

  index = 0

  while index < len(str):

    if str[index] == ch:

      return index

    index = index + 1

  return ­1def find(str, ch, start=0):

  index = start

  while index < len(str):

    if str[index] == ch:

      return index

    index = index + 1

  return ­1

Page 21: Tecnologie dell'Informazione e della Comunicazionegaspari/www/teaching/tic8.pdf · © Mauro Gaspari - University of Bologna - gaspari@cs.unibo.it Tecnologie dell'Informazione e della

© Mauro Gaspari - University of Bologna - [email protected]

Una definizione migliore di Punto

class Point:

  def __init__(self, x=0, y=0):

    self.x = x

    self.y = y

  def __str__(self):

    return '(' + str(self.x) + ', ' + str(self.y) + ')'

  def muovi(self,a,b):

 self.x = a

    self.y = b

Page 22: Tecnologie dell'Informazione e della Comunicazionegaspari/www/teaching/tic8.pdf · © Mauro Gaspari - University of Bologna - gaspari@cs.unibo.it Tecnologie dell'Informazione e della

© Mauro Gaspari - University of Bologna - [email protected]

Esempio

>>> p = Point(3, 4)>>> str(p)'(3, 4)'

>>> p = Point(3, 4)>>> print p(3, 4)

NB: __str__ overrides il comportamento standard di str

La print su un oggetto chiama str.

Page 23: Tecnologie dell'Informazione e della Comunicazionegaspari/www/teaching/tic8.pdf · © Mauro Gaspari - University of Bologna - gaspari@cs.unibo.it Tecnologie dell'Informazione e della

© Mauro Gaspari - University of Bologna - [email protected]

Uno script con la classe Pointclass Point:

  def __init__(self, x=0, y=0):

    self.x = x

    self.y = y

  def __str__(self):

    return '(' + str(self.x) + ', ' + str(self.y) + ')'

  def muovi(self,a,b):

    self.x = a

    self.y = b

b = Point(4,5)

b.muovi(6,7)

print(b)

NB. Gli oggetti sono mutabili!

Page 24: Tecnologie dell'Informazione e della Comunicazionegaspari/www/teaching/tic8.pdf · © Mauro Gaspari - University of Bologna - gaspari@cs.unibo.it Tecnologie dell'Informazione e della

© Mauro Gaspari - University of Bologna - [email protected]

Quando due oggetti sono uguali?

● Si è già discusso in precedenza del concetto di uguaglianza tra

elementi in Python.

● In genere il concetto di uguaglianza può essere definito in modi

diversi.

● Ad esempio “Abbiamo la stessa macchina” non significa di solito

che la macchina in questione sia lo stesso oggetto, ma piuttosto

che la marca e il modello sono gli stessi.

● Se si dice invece “Abbiamo la stessa Mamma” allora si tratta ella

stessa persona.

Page 25: Tecnologie dell'Informazione e della Comunicazionegaspari/www/teaching/tic8.pdf · © Mauro Gaspari - University of Bologna - gaspari@cs.unibo.it Tecnologie dell'Informazione e della

© Mauro Gaspari - University of Bologna - [email protected]

Quindi?

● L'idea di uguaglianza dipende dal contesto.

● Anche con gli oggetti nei linguaggi di programmazione c'è lo stesso tipo di ambiguità.

● Per esempio se si dice che due punti sono uguali:– Contengono le stesse coordinate?

– Sono lo stesso oggetto (stesso id).

Page 26: Tecnologie dell'Informazione e della Comunicazionegaspari/www/teaching/tic8.pdf · © Mauro Gaspari - University of Bologna - gaspari@cs.unibo.it Tecnologie dell'Informazione e della

© Mauro Gaspari - University of Bologna - [email protected]

Esempio

>>> p1 = Point(3,4)>>> p2 = Point(3,4)>>> p1 == p20>>> p2 = p1>>> p1 == p21

Page 27: Tecnologie dell'Informazione e della Comunicazionegaspari/www/teaching/tic8.pdf · © Mauro Gaspari - University of Bologna - gaspari@cs.unibo.it Tecnologie dell'Informazione e della

© Mauro Gaspari - University of Bologna - [email protected]

Tipi di equivalenza

● L'equivalenza su gli oggetti si dice anche equivalenza superficiale (= shallow equality) perchè confronta solo i riferimenti agli oggetti e non il contenuto.

● L'equivalenza che si basa invece sul contenuto degli oggetti si definisce equivalenza profonda (=deep equality).

Page 28: Tecnologie dell'Informazione e della Comunicazionegaspari/www/teaching/tic8.pdf · © Mauro Gaspari - University of Bologna - gaspari@cs.unibo.it Tecnologie dell'Informazione e della

© Mauro Gaspari - University of Bologna - [email protected]

Esempio

● Definizione di una deep equality sui punti.

samePoint(p1, p2) :  return (p1.x == p2.x) and (p1.y == p2.y)

Page 29: Tecnologie dell'Informazione e della Comunicazionegaspari/www/teaching/tic8.pdf · © Mauro Gaspari - University of Bologna - gaspari@cs.unibo.it Tecnologie dell'Informazione e della

© Mauro Gaspari - University of Bologna - [email protected]

Programmazione basata su oggetti

● La programmazione vista fino ad ora si chiama basata su oggetti (=object based).

● Un programma è costituito da un insieme di definizioni di classi e di operazioni sugli oggetti di queste classi.

● Cosa vuol dire allora orientato agli oggetti (=object oriented)?

Page 30: Tecnologie dell'Informazione e della Comunicazionegaspari/www/teaching/tic8.pdf · © Mauro Gaspari - University of Bologna - gaspari@cs.unibo.it Tecnologie dell'Informazione e della

© Mauro Gaspari - University of Bologna - [email protected]

Un oggetto rettangolo

class Rectangle:def __init__(self,width,height,x,y):

       self.corner = Point(x,y)       self.width = width       self.height = height

box = Rectangle(100.0,200.0,0.0,0.0)

NB. in questo modo abbiamo inclusoun oggetto dentro un altro.

Page 31: Tecnologie dell'Informazione e della Comunicazionegaspari/www/teaching/tic8.pdf · © Mauro Gaspari - University of Bologna - gaspari@cs.unibo.it Tecnologie dell'Informazione e della

© Mauro Gaspari - University of Bologna - [email protected]

Oggetti composti

Gli oggetti composti si accedono concatenandodiversi operatori punto:

>>> print box.corner.x

Page 32: Tecnologie dell'Informazione e della Comunicazionegaspari/www/teaching/tic8.pdf · © Mauro Gaspari - University of Bologna - gaspari@cs.unibo.it Tecnologie dell'Informazione e della

© Mauro Gaspari - University of Bologna - [email protected]

Esempio istanze come valori restituiti

def findCenter(box):  p = Point()  p.x = box.corner.x + box.width/2.0  p.y = box.corner.y + box.height/2.0  return p

>>> center = findCenter(box)>>> printPoint(center)(50.0, 100.0)

Page 33: Tecnologie dell'Informazione e della Comunicazionegaspari/www/teaching/tic8.pdf · © Mauro Gaspari - University of Bologna - gaspari@cs.unibo.it Tecnologie dell'Informazione e della

© Mauro Gaspari - University of Bologna - [email protected]

Copiare oggetti

● Anche gli oggetti come le liste hanno il problema dell'aliasing.

● Spesso conviene copiare oggetti per evitare il rischio di modifiche

indesiderate.

● Python fornisce il modulo copy proprio per questo.

>>> import copy>>> p1 = Point(3,4)>>> p2 = copy.copy(p1)>>> p1 == p20>>> samePoint(p1, p2)1

Page 34: Tecnologie dell'Informazione e della Comunicazionegaspari/www/teaching/tic8.pdf · © Mauro Gaspari - University of Bologna - gaspari@cs.unibo.it Tecnologie dell'Informazione e della

© Mauro Gaspari - University of Bologna - [email protected]

Osservazioni

● Attenzione la funzione copy.copy (ovvero la funzione copy nel modulo copy) realizza uno shallow copyng.

Page 35: Tecnologie dell'Informazione e della Comunicazionegaspari/www/teaching/tic8.pdf · © Mauro Gaspari - University of Bologna - gaspari@cs.unibo.it Tecnologie dell'Informazione e della

© Mauro Gaspari - University of Bologna - [email protected]

Esempi

def growRect(box, dwidth, dheight) :  box.width = box.width + dwidth  box.height = box.height + dheight

Per esercizio fare una funzione moveRect che sposta il rettangolo.

Page 36: Tecnologie dell'Informazione e della Comunicazionegaspari/www/teaching/tic8.pdf · © Mauro Gaspari - University of Bologna - gaspari@cs.unibo.it Tecnologie dell'Informazione e della

© Mauro Gaspari - University of Bologna - [email protected]

Osservazioni

● Se uso shallow copy ma growRect funziona bene mentre la moveRect sposterebbe entrambi i triangoli.

● Fortunatamente il modulo copy fornisce una funzione deepcopy che copia completamente un oggetto deferenziando (seguendo) i riferimenti che trova.

Page 37: Tecnologie dell'Informazione e della Comunicazionegaspari/www/teaching/tic8.pdf · © Mauro Gaspari - University of Bologna - gaspari@cs.unibo.it Tecnologie dell'Informazione e della

© Mauro Gaspari - University of Bologna - [email protected]

Esempi

>>> b2 = copy.deepcopy(b1)

# a questo punto b1 e b2 sono oggetti# completamente separati

def growRect(box, dwidth, dheight) : import copy newBox = copy.deepcopy(box) newBox.width = newBox.width + dwidth newBox.height = newBox.height + dheight return newBox