programmazione a oggetti tramite la macchina del caffé (pt. 3)
DESCRIPTION
Terza (e ultima) parte delle mie slides introuttive alla OOP con Java.TRANSCRIPT
La programmazione a oggetti e le macchine del caffé
(PARTE 3)
Prof. Marcello Missiroli
Di cosa parliamo
Finalizzazione
Ereditarietà multipla e Interfacce
Classi astratte
Aggregazione
Limitiamo l'ereditarietà
A volte è utile LIMITARE la possibilità di derivare (e quindi modificare) il comportamento di certi metodi o classi
Mantenendo il parallelo con la macchina del caffè, dobbiamo essere CERTI che tutte macchine usino llo stesso formato di capsule, per esempio.
Come si fa?
Occorre precedere il nome di ciò che ci interessa dalla parola chiave “final”
Una classe final è una classe che non può essere estesa
Un metodo final è un metodo che non può essere sovraccaricato nelle sottoclassi
Un attributo final è una variabile che può essere assegnata una sola volta (simile a una costante).
Esempio
public class Capsula {
public float Dimensioni() {...}
public final void Peso() {...}
}
public class MicroCapsula extends Capsula { … } → ERROR!
Estendiamo l'ereditarietà
• Nulla ci vieta, in teoria, di estendere il processo di ereditarietà e fare discendere il nostro oggetto da 2,3 o anche più oggetti.
• Di fatto, aggiungiamo oggetti e metodi ”di base” al nostro oggetto.
Troppo complicato!
Questo sistema è possibile in certi linguaggi (es. il C++), anche se intruduce una serie di problemi
Java usa un meccanismo leggermente diverso, chiamato Interfaccia
Torniamo alla nostra macchina
Supponiamo ora di occuparci dell'alimentazione della nostra macchina del caffè.
Una possibile soluzione consiste nell'agganciaci alla normale rete di alimentazione
Una seconda soluzione consiste nel mettere delle batterie
Una terza possibile soluzione consiste nell'usare accumulatori
In ogni caso..
Il sistema deve fornire le stesse funzionalità base:
Un pulsante di accensione/spegnimento
Corrente continua a 12V.
Aggiungiamo
L'interfaccia
public interface ElectricalAdapter {
static final int OUTPUT = 12.0f;String PlugType();int InputVoltage();
}
Cos'è?
E' una “specie” di classe, ma
* Possiede solo metodi, non attributi (al limite costanti statiche)
* Non ha implementazione, per cui non è istanziabile.
Cos'è?
E' una sorta di “promessa”. Si garantisce che si implementeranno quei metodi, un po' come quando si aderisce ad uno standard (.iso, .mp3).
Uso delle interfacce
public class MacchinaCaffeCappBattIta
implements ElecticalAdapter {
String PlugType(){return “Italian”;}
int InputVoltage(){return 220;};
}
DicharazioneDicharazionedi uso dell'di uso dell'interfacciainterfaccia
Realizzazione (anche gergo UML)
Perché darsi questa pena?
Le implementazioni possono variare anche parecchio, ma il funzionamento osservabile è identico.
Quindi la macchina funziona e fa il caffé. Può essere alimentata a batterie, con la corrente o con fluttuazioni nanotropiche del subspazio.
E i dettagli non ci interessano!
Altra implementazione
public class MacchinaCaffeCappBattUs
implements ElecticalAdapter {
String PlugType(){return “Usa”;}
int InputVoltage(){return 110;};
}
Altra implementazione
public class MacchinaCaffeCappBattBattery
implements ElecticalAdapter {
String PlugType(){return “”;}
int InputVoltage(){return 0;};
}
Anche le interfacce...
Nel loro piccolo, hanno delle gerarchie.
E' possibile estendere una interfaccia per compiti più specializzati.
Sistema molto utilizzato (per esempio in Swing e nelle Eccezioni)
Classi e metodi astratti
In certi casi si possono definire alcune classi o metodi come “astratti” - analogamente alle interfacce. Basta precederli con la parola chiave 'abstract'.
Anche in questo caso le tali classi non possono essere istanziati.
Un solo metodo virtuale rende virtuale l'intera classe
Classi e metodi astratti (2)
Di solito si preferisce l'uso delle interfacce, che offrono più libertà di derivazione
Le classi astratte sono utilizzate spesso nella parte iniziale di una progettazione OOD
Binding
In generale, nei linguaggi non OO, la decisione su quale funzione viene eseguita avviene sempre in fase di compilazione.
Nel caso degli oggetti, invece, la decisione può essere ritardata alla fase di esecuzione (Late binding)
In pratica
Anche se Java è un linguaggio fortemente tipizzato, è possibile assegnare ad una variabile non solo un oggetto del tipo previsto, ma anche uno dei suoi figli
Il messaggio che inviate all'oggetto è lo stesso, ma l'effetto può variare.
Esempio
Supponiamo di avere un'applicazione che gestisce tre macchine del caffé e può controllarle tutte.
Creiamo un'array di macchine di caffé, ma una di queste fa anche il cappuccino.
Codice
MacchinaCaffe arr[] = new MacchinaCaffe[3];
arr[0]= new MacchinaCaffe();
arr[1]= new MacchinaCaffe();
arr[2]= new MacchinaCaffeCappuccio(2,2,2);
arr[0].make_coffee(10);
arr[2].make_coffee(10);
Esegue il metodo Esegue il metodo della classe della classe MacchinaCaffeMacchinaCaffe
Esegue il metodo della classe MacchinaCaffecappuccioEsegue il metodo della classe MacchinaCaffecappuccio
Ultimi dettagli di OOD
Ereditarietà.....
L'ereditarietà non è l'unico modo per estendere le funzionalità del codice mantenendone l'integrità e una elevata riusabilità.
Tipicamente, quando si creano sottoclassi si estendono le funzionalità esistenti tramite l'override
Si usano classi/metodi astratti quando si vuole una certa funzionalità ma non si sa bene come implementarla
...o aggregazione?
Un altro modo per creare funzionalità è l'aggregazione (o la composizione).
In questo modo, si prendono altre classi e si combinano in una nuova classe.
Si fornisce una nuova metodologia per renderlo compatibile col codice esistente
Quale scegliere?
In molti casi, la scelta è obbligata e ovvia. In altri, sono possibili entrambe le strade e c'è un criterio preciso. Ci si basa sull'esperienza.
Esempio: Da “punto” a “linea”. Da “Macchina da caffe” a “Macchina da caffè con batteria”
Riassumendo
Abbiamo così terminato questa breve introduzione del mondo della programmazione OOP tramite Java.
Spero abbia gettato un po' di luce su questa “nuova” modalità di programmazione. (Per la verità se ne parla dal 1960, e si usa concretmente dagli anni novanta!)
Licenza
Questo documento è soggetto alla licenza Creative Common BY-SA (Attribution – Share Alike)