Programmazione a oggetti tramite la macchina del caffé (pt. 3)

Post on 13-Jun-2015

407 views 3 download

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)