Lezione 10
Programmazione a oggetti
Programmazione per la Musica | Prof. Luca A. Ludovico
Introduzione
• Obiettivi:
– Definire classi contenenti variabili, metodi e
costruttori
– Istanziare oggetti di tali classi
– Usare l’operatore “.” per accedere a variabili e
metodi delle classi
– Apprendere l’uso dei modificatori d’accesso public
e private
– Creare gerarchie di classi con ereditarietà
– Apprendere l’uso dei modificatori protected, final e
static
Programmazione per la Musica - Prof. Luca A. Ludovico
10. Programmazione a oggetti
Ereditarietà
• Ereditarietà: permette di derivare nuove classi a partire da quelle
già definite realizzando una gerarchia di classi. Una classe
derivata (sottoclasse o classe figlia) mantiene i metodi e gli
attributi delle classi da cui deriva (classi base, superclassi o classi
padre); inoltre, può definire i propri metodi o attributi, e
ridefinire il codice di alcuni dei metodi ereditati tramite un
meccanismo chiamato overriding
• Una sottoclasse è più specializzata rispetto alla sua superclasse;
analogamente, una superclasse è più generica rispetto a una
sottoclasse
• JAVA (come C++) supporta solo l’ereditarietà singola: un figlio
può avere un solo padre → la gerarchia tra classi forma un albero
Programmazione per la Musica - Prof. Luca A. Ludovico
10. Programmazione a oggetti
Esempio di ereditarietà
• Si consideri il rapporto gerarchico tra la superclasse
Animale e la sottoclasse Felino:
– l’attributo genere sarà comune a tutti gli animali, il cui genere sarà
sempre maschile o femminile, al limite indefinito;
– Il metodo calcolaEta, che combina l’attributo data_nascita con la
data corrente per restituire il numero di anni dell’esemplare, sarà
definito nella superclasse, e rimarrà valido per tutte le sottoclassi
che ereditano (l’età si calcola allo stesso modo per tutti gli esseri
viventi)
– un felino avrà però dei descrittori più specifici rispetto a un generico
animale (si pensi al colore del pelo, attributo che non avrebbe senso
per un generico animale, che potrebbe essere squamato, piumato,
ecc.)
Programmazione per la Musica - Prof. Luca A. Ludovico
10. Programmazione a oggetti
Dichiarazione di sottoclassi
class MiaClasse
{
…
}
La dichiarazione precedente è minimale, in quanto
racchiude solo componenti strettamente richiesti. Si può
ad esempio stabilire una relazione gerarchica tra classe
padre e classe figlia tramite la sintassi:
class MiaClasse extends MiaSuperClasse
{
…
}
Programmazione per la Musica - Prof. Luca A. Ludovico
10. Programmazione a oggetti
La gerarchia di classi in Java
• Tutte le classi ereditano dalla superclasse Object: è la classe più
generale di tutte, e definisce comportamenti comuni a tutte le
classi.
• Le classi inferiori nella gerarchia mettono a disposizione
comportamenti più specifici e possono sovrascrivere e/o
nascondere i metodi delle classi più generali
Programmazione per la Musica - Prof. Luca A. Ludovico
10. Programmazione a oggetti
La gerarchia di classi in JAVA
• La superclasse Object contiene metodi generali, disponibili a
tutte le classi che ereditano (quindi a tutte le classi), tra cui:
– Object clone()
crea e restituisce una copia dell’oggetto corrente
– boolean equals(Object obj)
indica se un altro oggetto è uguale a questo
– String toString()
restituisce una rappresentazione a stringa di testo dell’oggetto
• Esempio: invocare il metodo toString() su una classe definita
dall’utente che non ne contiene una propria versione
• Esempio: ridefinire il metodo toString() in una classe definita
dall’utente
Programmazione per la Musica - Prof. Luca A. Ludovico
10. Programmazione a oggetti
Assegnamento tra oggetti
• L’operatore di assegnamento funziona tra oggetti della stessa
classe
• Poichè una superclasse è più generica di una sottoclasse:
–
–
è sempre possibile assegnare un oggetto di una sottoclasse a un oggetto di
una superclasse.
non è possibile (e genera errore a compile-time) assegnare un oggetto di una
superclasse a un oggetto di una sottoclasse
• Esempio
MusicSymbol a = new MusicSymbol ();
MusicSymbol b = new MusicSymbol ();
a = b; // ok
MusicNote n = new MusicNote(); // MusicNote eredita da MusicSymbol
a = n; // ok
n = a; // no!!!
Programmazione per la Musica - Prof. Luca A. Ludovico
10. Programmazione a oggetti
Cast delle variabili
• Tramite il cast si può specificare al compilatore che un oggetto di
classe A è della classe B più specifica
Object o = "str"; String str = (String)o;
• Possibili errori: effettuare il cast di oggetti che appartengono
–
a rami diversi della gerarchia
String o = "str"; Integer i = (Integer)o; // Errore a compile-time
–
allo stesso ramo ma cmq non sono “castabili”, il che solleva a run-time
un’eccezione ClassCastException
Number o = new Integer(5);
Double n = (Double)o; // Solleva ClassCastException
• Uso tipico: passare da un tipo più generale a uno più specifico. Ad
esempio Integer eredita da Number (tutti gli interi sono numeri
ma non viceversa: ad esempio Double, Float, Byte, Long)
Programmazione per la Musica - Prof. Luca A. Ludovico
10. Programmazione a oggetti
I modificatori d’accesso protected e (default)
• Protected può essere attribuito solo ai metodi e alle variabili
interne alla classe e non può essere applicato alla classe stessa
• I metodi e le variabili dichiarate come protected sono visibili da
classi dichiarate nello stesso package e da sottoclassi e classi
derivate dichiarate ovunque
• Se non viene specificato nulla, il compilatore considera un
modificatore d’accesso detto di default.
–
–
Un membro di una classe (metodo o attributo) per default sarà accessibile
solo dalle classi appartenenti al package dove è definito
Una classe appartenente ad un package definita senza il modificatore public
sarà visibile solo dalle classi appartenenti allo stesso package
Programmazione per la Musica - Prof. Luca A. Ludovico
10. Programmazione a oggetti
Specchietto riassuntivo
• I modificatori di accesso sono 3: private, protected e public
• In assenza di questi tre, un elemento di programma viene
considerato package-local o friend (si dice che assume la visibilità
di default)
• Le visibilità possibili sono:
Modificatore
Stessa classe
Stesso package
Sottoclasse
Ovunque
Public
sì
sì
sì
sì
Protected
sì
sì
sì
no
(default)
sì
sì
no
no
Private
no
no
no
no
Programmazione per la Musica - Prof. Luca A. Ludovico
10. Programmazione a oggetti
Polimorfismo e override
• Una classe che eredita può richiedere la riscrittura e la
specializzazione di metodi ereditati. Nella programmazione ad
oggetti l’override è l'operazione di riscrittura di un metodo
ereditato
• Il metodo che effettua override deve avere lo stesso nome, stesso
numero e tipo di parametri, e stesso tipo restituito rispetto a
quello originario
–
può anche restituire un sottotipo del tipo restituito (covariant return type)
• Polimorfismo (dal greco "avere molte forme"): un’interfaccia,
molte implementazioni. I metodi che vengono ridefiniti in una
sottoclasse sono detti polimorfi, in quanto lo stesso metodo si
comporta diversamente a seconda del tipo di oggetto su cui è
invocato
Programmazione per la Musica - Prof. Luca A. Ludovico
10. Programmazione a oggetti
Polimorfismo dei metodi: overload e override
• Dal punto di vista implementativo il polimorfismo per i metodi si
ottiene utilizzando l'overload e l'override dei metodi stessi.
• Ogni metodo è identificato dal nome, ma è univocamente
determinato anche dalla lista dei parametri. Ciò permette di
avere all'interno di una classe più metodi che hanno lo stesso
nome, ma con parametri diversi
• L'overload si basa sulla scrittura di più metodi identificati dallo
stesso nome che però hanno, in ingresso, parametri di tipo e in
numero diverso
• Con il termine override si intende una vera e propria riscrittura di
un certo metodo di una classe che si eredita. Dunque,
necessariamente, l'override implica ereditarietà
Programmazione per la Musica - Prof. Luca A. Ludovico
10. Programmazione a oggetti
Il modificatore final
• Final significa letteralmente «finale» o «non
mutabile»
• Tale modificatore, al pari di public e private, può
essere preposto a un metodo, a un attributo o ad una
classe:
– preposto a una variabile la rende una costante per l'istanza della
classe
– preposto a un metodo, implica che in un contesto di ereditarietà su
di esso non potrà essere eseguito l'override da parte della classe che
eredita
– una classe definita final non può essere ereditata. Questo
semanticamente significa che la classe non necessita di
specializzazioni o estensioni
Programmazione per la Musica - Prof. Luca A. Ludovico
10. Programmazione a oggetti
Il modificatore static
• Applicabile a metodi e attributi di una classe
• Dichiarare un metodo static lo rende di fatto comune
a tutte le istanze della classe. La chiamata del
metodo avviene senza istanziare la classe:
• Anziché [nomeOggetto].[nomeMetodo]() si
usa [nomeClasse].[nomeMetodo]()
• Dichiarare un attributo static lo rende comune a tutte
le istanze della classe
– Un attributo public static è di fatto una variabile globale
Programmazione per la Musica - Prof. Luca A. Ludovico
10. Programmazione a oggetti
ESEMPIO
NoteExercise.java
Il codice implementa l’ereditarietà tra una super-classe NoteRest (che rappresenta
gli aspetti ritmici di un simbolo musicale, comuni a note e pause) e una sotto-classe
Note, che la specializza con l’informazione sull’altezza e con opportuni metodi.
Programmazione per la Musica - Prof. Luca A. Ludovico
10. Programmazione a oggetti
ESERCIZIO
Si implementi una classe che descrive singole note, distinta dalla classe principale
che contiene il metodo main del software.
Per quanto riguarda l’altezza, si utilizzi internamente la Continuous Binomial
Representation (cbr), esponendo metodi che permettono di estrapolare
l’informazione di ottava, pitch class e name class.
Si protegga opportunamente l’accesso alla codifica interna dell’altezza, impedendo
al metodo main di assegnare valori cbr inesistenti alle istanze delle note.
Programmazione per la Musica - Prof. Luca A. Ludovico
10. Programmazione a oggetti
Scarica

Presentazione del corso