1 / 62

Interfacce

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);

kellan
Download Presentation

Interfacce

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. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. Interfacce

  2. Interfacce • Dichiarazionidi tipi riferimentochedescrivonooggetti in modoastratto • Specificano solo le firmedeimetoditralasciandotuttigliaspettidiimplementazione

  3. Interfacce interface Polynomial { public void somma(Polynomial p); public void derivata(); public intgrado(); public double coeff(intgrado); }

  4. Interfacce interface Collection<E> { public void add(E element); public void remove(E element); public boolean find(E element); . . . }

  5. Classi implementano Interfacce • La keyword implementsindicacheunaclasseimplementaunainterfaccia class ArrayPoly implements Polynomial { ... } class TreeSet<E> implements Collection<E> { ... }

  6. Classi implementano Interfacce • Unaclassecheimplementaunainterfacciadeveimplementaretuttiimetodidell’interfaccia • Tutti I metodidell’interfacciadevonoesseredichiarati public nellaclasse • Nullavietache la classedichiarialtrimetodioltrequellidell’interfacciacheimplementa

  7. Classi implementano Interfacce • Unainterfacciapuòessereimplementatadapiùclassi class ArrayPoly implements Polynomial { ... } class ListPoly implements Polynomial { ... }

  8. Classi implementano Interfacce • Unainterfacciapuòessereimplementatadapiùclassi class HashMap<E> implements Collection<E>{ ... } class TreeSet<E> implements Collection<E> { ... }

  9. Conversioni di tipo • Unainterfaccia “rappresenta” tutte le classiche la implementano • Il tipointerfacciasipuòassociare a tuttiglioggettidelleclassiche la implementano Continua…

  10. 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…

  11. Conversioni di tipo • La conversione è lecita solo in determinate situazioni • Problema: TreeSet<Double>() non implementaPolynomial Polynomial x = new TreeSet<Double>(); // ERRORE

  12. 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…

  13. 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

  14. ConversionidiTipo • Le conversioniabilitatedallaregola C<: IsseCimplementaI sonocorrette • Dimostrazioneintuitiva: • Se CimplementaI , CdevedefiniretuttiimetodidichiaratidaI(e dichiararli public) • Quinditutti le invocazionidimetodoammessedaItrovanoeffettivamente un metododefinito in C Continua…

  15. 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…

  16. Polimorfismo – dynamic dispatch • Possiamoinvocareognunodeimetodidell’interfaccia: • Qualemetodoinvoca? int g = p.grado();

  17. 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…

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

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

  20. GWin • Un contenitorediQuadratie Cerchi • /** • UnafinestrachecontieneQuadrati e Cerchi • */ • class GWin • { • /** • Disegnatutte le formediquesto component • */ • public void paint(){ /* disegnasu g */ } • /** • Componentegraficasu cui disegnare • */ • private Graphics2D g; • }

  21. 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?

  22. 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); }

  23. 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 . . . }}

  24. 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); } }

  25. Quadrato Car Cerchio GWin Shape Diagramma delle Classi

  26. AncoraInterfacce

  27. Esempio • DefiniamounaclasseDataSetchepermettedicondurrealcunesemplicianalisisu un insiemedicontibancari • calcolodellamedia degliimporti del saldo • calcolodel conto con ilvaloremassimotraisaldi Continua…

  28. 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; }

  29. Esempio • Oraripetiamol’esempio per definireunaversionedellaclasseDataSetchepermettedicondurrealcunesemplicianalisisu un insiemedicorsiuniversitari: • calcolodellamedia del numerodistudenti per corso • calcolodel corso con massimonumerodistudenti class Corso{// . . . public double iscritti() { // ... }}

  30. 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; }

  31. 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(); }

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

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

  34. 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; }

  35. DataSetDiagramma UML Corso implementa dipende

  36. Interfacce standard • Le librerie Java forniscono molte interfacce standard, che possono essere utilizzare nella programmazione • Un esempio: • ActionListener

  37. 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);}

  38. 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…

  39. 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…

  40. 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

  41. Esempio: countdown • Un timer che esegue il countdown

  42. 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); } }

  43. 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

  44. 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; }

  45. 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

  46. 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() { ... }}

  47. Measurable Shapes • Ora possiamo passare Quadratie Cerchisia all’interno della classe Gwinper essere disegnati, sia all’interno della classe DataSetper essere misurati

  48. Conversioni di tipo • Unainterfaccia “rappresenta” tutte le classiche la implementano • Più in generale: un supertiporappresentatuttiisuoisottotipi Continua…

  49. 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…

  50. 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() {. . . } }

More Related