interfacce n.
Download
Skip this Video
Loading SlideShow in 5 Seconds..
Interfacce PowerPoint Presentation
Download Presentation
Interfacce

Loading in 2 Seconds...

play fullscreen
1 / 62

Interfacce - PowerPoint PPT Presentation


  • 130 Views
  • Uploaded on

Interfacce. Interfacce. Dichiarazioni di tipi riferimento che descrivono oggetti in modo astratto Specificano solo le firme dei metodi tralasciando tutti gli aspetti di implementazione. Interfacce. interface Polynomial { public void somma (Polynomial p);

loader
I am the owner, or an agent authorized to act on behalf of the owner, of the copyrighted work described.
capcha
Download Presentation

PowerPoint Slideshow about 'Interfacce' - kellan


An Image/Link below is provided (as is) to download presentation

Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author.While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server.


- - - - - - - - - - - - - - - - - - - - - - - - - - E N D - - - - - - - - - - - - - - - - - - - - - - - - - -
Presentation Transcript
interfacce1
Interfacce
  • Dichiarazionidi tipi riferimentochedescrivonooggetti in modoastratto
  • Specificano solo le firmedeimetoditralasciandotuttigliaspettidiimplementazione
interfacce2
Interfacce

interface Polynomial { public void somma(Polynomial p);

public void derivata();

public intgrado();

public double coeff(intgrado);

}

interfacce3
Interfacce

interface Collection<E> { public void add(E element);

public void remove(E element);

public boolean find(E element);

. . .

}

classi implementano interfacce
Classi implementano Interfacce
  • La keyword implementsindicacheunaclasseimplementaunainterfaccia

class ArrayPoly implements Polynomial { ... }

class TreeSet<E> implements Collection<E>

{ ... }

classi implementano interfacce1
Classi implementano Interfacce
  • Unaclassecheimplementaunainterfacciadeveimplementaretuttiimetodidell’interfaccia
  • Tutti I metodidell’interfacciadevonoesseredichiarati public nellaclasse
  • Nullavietache la classedichiarialtrimetodioltrequellidell’interfacciacheimplementa
classi implementano interfacce2
Classi implementano Interfacce
  • Unainterfacciapuòessereimplementatadapiùclassi

class ArrayPoly implements Polynomial { ... }

class ListPoly implements Polynomial

{ ... }

classi implementano interfacce3
Classi implementano Interfacce
  • Unainterfacciapuòessereimplementatadapiùclassi

class HashMap<E> implements Collection<E>{ ... }

class TreeSet<E> implements Collection<E>

{ ... }

conversioni di tipo
Conversioni di tipo
  • Unainterfaccia “rappresenta” tutte le classiche la implementano
  • Il tipointerfacciasipuòassociare a tuttiglioggettidelleclassiche la implementano

Continua…

conversioni di tipo1
Conversioni di tipo
  • Possiamoassegnareun riferimentoditipoclasse ad unavariabileditipointerfacciapurchè la classeimplementil’interfaccia

Collection<Double> c = new TreeSet<Double>();

Collection<Double> d = new HashMap<Double>();

Polynomial p = new ArrayPoly();

Polynomial q = new ListPoly();

Continua…

conversioni di tipo2
Conversioni di tipo
  • La conversione è lecita solo in determinate situazioni
  • Problema: TreeSet<Double>() non implementaPolynomial

Polynomial x = new TreeSet<Double>(); // ERRORE

conversioni di tipo3
ConversionidiTipo
  • Sottotipo (<:)
    • La relazionechepermettedideciderequando è lecitoconvertireun tiporiferimento in un altro
    • Per ilmomentodiciamo
  • Principio disostituibilità
    • Ovunquecisiaspetti un riferimentodi un tipo è lecitoutilizzare un rifetimentodi un sottotipo

S <: T sse

  • S è unaclasse, T è unainterfaccia
  • S implementaT.

Continua…

conversioni di tipo4
ConversionidiTipo
  • Assumiamo S <: T
  • Regoladiassegnamento
    • Un riferimentoditipoS sipuosempreassegnare ad unavariabileditipoT
    • Un riferimentoditipoclassepuòsempreessereassegnato ad unavariabileditipointerfacciache la classeimplementa
  • Regoladipassaggiodiparametri
    • Un riferimentoditipoS sipuosemprepassare per un parametroditipoT
    • Un riferimentoditipoclassepuòsempreesserepassato per un parametroditipointerfacciache la classeimplementa
conversioni di tipo5
ConversionidiTipo
  • Le conversioniabilitatedallaregola

C<: IsseCimplementaI

sonocorrette

  • Dimostrazioneintuitiva:
    • Se CimplementaI , CdevedefiniretuttiimetodidichiaratidaI(e dichiararli public)
    • Quinditutti le invocazionidimetodoammessedaItrovanoeffettivamente un metododefinito in C

Continua…

polimorfismo dynamic dispatch
Polimorfismo – dynamic dispatch
  • Le regole del linguaggiogarantisconocheunavariabileditipointerfaccia ha sempre come valore un riferimentodiunaclassecheimplemental’interfaccia
  • Se unainterfaccia è implementatadapiùclassi, iltipodeivalorilegatiallavariabilepuòcambiare

Polynomial p;

p= new ListPoly(...);p = new ArrayPoly(...);

Continua…

polimorfismo dynamic dispatch1
Polimorfismo – dynamic dispatch
  • Possiamoinvocareognunodeimetodidell’interfaccia:
  • Qualemetodoinvoca?

int g = p.grado();

polimorfismo dynamic dispatch2
Polimorfismo – dynamic dispatch

int g = p.grado();

  • Se priferisce un ListPoly, invocailmetodoListPoly.grado()
  • Se priferisceun ArrayPoly,invocailmetodoArrayPoly.grado();
  • Polimorfismo (molteforme):
    • ilmetodoinvocatodipendedipendedaltipodel riferimento legato allavariabile

Continua…

esempio
Esempio
  • Costruiamounaapplicazione per disegnare un insiemediformegeometrichecontenute in unacomponentegrafico:
    • definiamoGWin, unaclassechedescrive un contenitorediformegeometrichedisegnatemedianteunainvocazione del metodopaint()
    • per esemplificare, consideriamo due tipi diforme:QuadratoeCerchio
forme grafiche
Forme grafiche

class Quadrato{ . . . public void draw(Graphics2D g) {// Istruzioni per ildisegno . . . }}

class Cerchio{ . . . public void draw(Graphics2D g) {// Istruzioni per ildisegno . . . }}

slide20
GWin
  • Un contenitorediQuadratie Cerchi
  • /**
  • UnafinestrachecontieneQuadrati e Cerchi
  • */
  • class GWin
  • {
  • /**
  • Disegnatutte le formediquesto component
  • */
  • public void paint(){ /* disegnasu g */ }
  • /**
    • Componentegraficasu cui disegnare
    • */
  • private Graphics2D g;
  • }
domanda
Domanda
  • Che struttura utilizziamo per memorizzare le forme contenute nella GWin?
  • Come definiamo il metodo paint() in modo che disegni tutte le forme della componente?
risposte
Risposte
  • definiamo una nuova interfaccia: Shape
  • Ridefiniamo le classi Quadrato e Cerchio in modo che implementino Shape
  • Memorizziamo gli oggetti della componente in una ArrayList<Shape>

interface Shape { void draw(Graphics2D g); }

shapes
Shapes

class Quadrato implements Shape

{ . . . public void draw(Graphics2D g) {// Istruzioni per ildisegno . . . }}

class Cerchio implements Shape

{ . . . public void draw(Graphics2D g) {// Istruzioni per ildisegno . . . }}

slide24
GWin

Mantiene una ArrayList<Shape>

class GWin

{

private Graphics2D g;

private ArrayList<Shape> shapes;

// crea una GWin con un insieme di forme

public GWin(Shape... shapes)

{

Graphics2D g = new Graphics2D();

this.shapes = new ArrayList<Shape>();

for (Shape s:shapes) this.shapes.add(s);

}

// disegna tutte le componenti della GWin

public void paint()

{

for (Shape s:shapes) s.draw(g);

}

}

esempio1
Esempio
  • DefiniamounaclasseDataSetchepermettedicondurrealcunesemplicianalisisu un insiemedicontibancari
    • calcolodellamedia degliimporti del saldo
    • calcolodel conto con ilvaloremassimotraisaldi

Continua…

dataset
DataSet

public class DataSet { public void add(BankAccount x) { sum = sum + x.getBalance(); if (count == 0 || maximum.getBalance() < x.getBalance()) maximum = x; count++; } public BankAccount getMaximum() { return maximum; } public double average()

{return (count>0)? sum/count : Double.NaN; } private double sum; private BankAccount maximum; private int count; }

esempio2
Esempio
  • Oraripetiamol’esempio per definireunaversionedellaclasseDataSetchepermettedicondurrealcunesemplicianalisisu un insiemedicorsiuniversitari:
    • calcolodellamedia del numerodistudenti per corso
    • calcolodel corso con massimonumerodistudenti

class Corso{// . . .

public double iscritti() { // ... }}

dataset versione per corso
DataSet– versione per Corso

public class DataSet{ public void add(Corsox) { sum = sum + x.iscritti(); if (count == 0 || maximum.iscritti() < x.iscritti()) maximum = x; count++; } public CorsogetMaximum() { return maximum; } public double average()

{return (count>0)? sum/count : Double.NaN; } private double sum; private Corso maximum; private int count; }

interfacce riuso di codice
Interfacce riuso di codice
  • Il meccanismodianalisideidati è sempre lo stesso;
    • sibasasull’estrazionediunamisura
    • la differenza è solo nell’implementazione del metodochefornisce la misura
  • Possiamouniformare:
    • è sufficientestabilireunamodalitàuniforme per estrarre la misura.

interfaceMeasurable { double getMeasure(); }

measurable bankaccounts
Measurable BankAccounts

public class BankAccount implements Measurable { public double getMeasure() { return getBalance(); } // ...}

Continua…

measurable corsi
Measurable Corsi

class Corsoimplements Measurable { public double getMeasure() { return iscritti(); } // . . . }

dataset versione generica
DataSet – versionegenerica

public class DataSet{ public void add(Measurable x) { sum = sum + x.getMeasure(); if (count == 0 || maximum.getMeasure() < x.getMeasure()) maximum = x; count++; } public Measurable getMaximum() { return maximum; } public double average() { return sum/count; } private double sum; private Measurable maximum; private int count; }

dataset diagramma uml
DataSetDiagramma UML

Corso

implementa

dipende

interfacce standard
Interfacce standard
  • Le librerie Java forniscono molte interfacce standard, che possono essere utilizzare nella programmazione
  • Un esempio:
    • ActionListener
actionlistener
ActionListener
  • Descrive oggetti che svolgono il ruolo di gestori di eventi:
    • rimane attesa (in ascolto) di un evento, per poi rispondere con una azione al momento in cui l’evento si manifesta

interface ActionListener{   void actionPerformed(ActionEvent event);}

esempio eventi di un timer
Esempio: eventi di un timer
  • Eventinotificatiad un ActionListenerassociatoal timer
  • Il gestorevieneattivato ad ogni tick del timer,
    • actionPerformed() invocato ad ogni tick
    • event: contieneinformazionesull’evento

public interface ActionListener{   void actionPerformed(ActionEvent event);}

Continua…

esempio eventi di un timer1
Esempio: eventi di un timer
  • La gestione dell’evento avviene nel metodo actionPerformed()
  • Gestioni diverse realizzate da classi diverse che implementano ActionListener

class TimerListenerimplements ActionListener{     public void actionPerformed(ActionEvent event)    {      // Eseguito ad ogni tick.

    }}

Continua…

esempio eventi di un timer2
Esempio: eventi di un timer
  • Per associare un particolare listener al timer è necessario registrare il listener sul timer
  • Ora possiamo far partire il timer

TimerListenerlistener = new TimerListener();Timer t = new Timer(interval, listener);

tra due tick

t.start(); // Esegue in un thread separato

esempio countdown
Esempio: countdown
  • Un timer che esegue il countdown
countdownlistener
CountDownListener

public class CountDownApp

{

public static void main(String[] args)

{

CountDownListener listener = new CountDownListener(10);

// Milliseconditra due tick

final int DELAY = 1000;

Timer t = new Timer(DELAY, listener);

t.start();

JOptionPane.showMessageDialog(null, "Quit?");

System.exit(0);

}

}

countdownlistener1
CountDownListener
  • Inizializza un contatore al valore passato nel costruttore
  • Ad ogni invocazione del metodo actionPerformed()
    • controlla il valore del contatore e dà in output il messaggio corrispondente
    • decrementa il contatore
countdownlistener2
CountDownListener

classCountDownListenerimplementsActionListener

{

public CountDownListener(int initialCount)

{

count = initialCount;

}

public void actionPerformed(ActionEvent event)

{

if (count >= 0) System.out.println(count);

if (count == 0) System.out.println("Liftoff!");

count--;

}

private int count;

}

interfacce multiple
Interfacce multiple
  • Una classe può implementare più di una interfaccia
  • In quel caso deve definire, public, tutti i metodi delle interfacce che implementa
  • E’ automaticamente sottotipo di ciascuna delle interfacce che implementa
measurable shapes
Measurable Shapes

class Quadrato implements Shape, Measurable

{ . . . public void draw(Graphics2D g) { ... } public double getMeasure() { ... } }

class Cerchio implements Shape, Measurable

{ . . . public void draw(Graphics2D g){ ... }public void getMeasure() { ... }}

measurable shapes1
Measurable Shapes
  • Ora possiamo passare Quadratie Cerchisia all’interno della classe Gwinper essere disegnati, sia all’interno della classe DataSetper essere misurati
conversioni di tipo6
Conversioni di tipo
  • Unainterfaccia “rappresenta” tutte le classiche la implementano
  • Più in generale: un supertiporappresentatuttiisuoisottotipi

Continua…

conversioni di tipo7
Conversioni di tipo
  • Principio disostituibilità
    • Un riferimentodi un sottotipopuòessereusatoovunquecisiaspetti un riferimentodi un supertipo
  • Puòcausareperditadiinformazione
    • nelcontesto in cui ciaspettiamoilsupertipo, non possiamousare solo I metodi del supertipo
    • perdiamo la possibilitàdiutilizzareglieventualimetodiaggiuntivi del sottotipo

Continua…

ancora shapes
AncoraShapes

class Car implements Shape

{ . . .public void draw(Graphics2D g){ . . . }public String brand() {. . . }

}

class Smiley implements Shape

{ . . .public void draw(Graphics2D g){ . . . }public String mood() {. . . }

}

sottotipi e perdita di informazione
Sottotipi e perditadiinformazione
  • Consideriamo

public static void printBrand(List<Shape> l)

{ for (Shape s : l)

// stampa la marca di tutte le macchine di l

// ???

}

Continua…

sottotipi e perdita di informazione1
Sottotipi e perditadiinformazione
  • Certamente non possiamo fare così …

public static void printBrand(List<Shape> l)

{ for (Shape s : l)

// stampa la marca di tutte le macchine di l

System.out.println( s.brand() ); // TYPE ERROR!

}

Continua…

slide53
Cast
  • Permette di modificare il tipo associato ad una espressione
  • Un cast è permesso dal compilatore solo se applica conversioni tra tipi compatibili
  • Compatibili = sottotipi (per il momento)
  • Anche quando permesso dal compilatore, un cast può causare errore a run time
  • Se s non è un Car errore a run time

((Car)s).brand()

Continua…

tipo statico e dinamico
Tipostatico e Dinamico
  • Tipostatico e tipodinamicodiunavariabile
    • tipostatico: quellodichiarato
    • tipodinamico: iltipo del riferimentoassegnatoallavariabile
  • Il tipodinamicopuòcambiaredurantel’esecuzione, ma le regolegarantisconoche
    • Il tipodinamicodiunavariabile è sempre un sottotipo del tipostaticodellavariabile

Continua…

slide55
Cast
  • (T)varcausaerrore
    • in compilazione

se T non è compatibile con iltipostaticodivar

    • in esecuzione (ClassCastException)

se T non è compatibile con iltipodinamicodivar

Continua…

slide56
Cast
  • OK: Car sottotipo di Shape
  • Compila correttamente
    • il tipo dichiarato dis è Shape
    • Car e Shape sono compatibili
  • Esegue correttamente
    • s è un Car (il tipo dinamico di s è Car)

Shape s = new Car();

Car c = (Car) s

Continua…

slide57
Cast
  • OK: Car sottotipo di Shape
  • Compila correttamente
    • il tipo dichiarato dis è Shape
    • Smiley e Shape sono compatibili
  • Errore a run time
    • s non è uno Smiley

Shape s = new Car();

Smiley c = (Smiley) s

Continua…

slide58
Cast
  • Attenzione anche qui …

public static void printBrand(List<Shape> l)

{ for (Shape s : l)

// ClassCastException se s instance of Smiley

System.out.println( ((Car)s).brand() );

}

Continua…

instanceof
instanceof
  • Permette di determinare il tipo dinamico di una variabile
  • Quindi permette di evitare errori in esecuzione
  • Esegue correttamente, perchè xè sicuramente un T

x istanceof T è true solo se xha tipo dinamico T

if (x instanceof T) return (T) x

slide60
Cast
  • Questo, finalmente, è corretto

public static void printBrand(List<Shape> l)

{ for (Shape s : l)

if (s instanceof Car)

System.out.println( ((Car)s).brand() );

}

domanda1
Domanda
  • Come disegnare solo le Shapes che sono Cars?
risposta
Risposta

// disegna tutte le Cars della GWin

public void paint(){

for (Shape c:shapes)

if (c instanceof Car) c.draw(g);

}