Programmazione Java: Le classi interne Romina Eramo [email protected] http://www.di.univaq.it/romina.eramo/tlp Romina Eramo Tecnologie dei Linguaggi di Programmazione DISIM - Dipartimento di Ingegneria e Scienze dell’Informazione e Matematiche Roadmap › › › › › › Classi interne Creazione di classi interne Collegamento alla classe esterna Utilizzo di .this e .new Classi interne e upcasting Classi anonime Romina Eramo Tecnologie dei Linguaggi di Programmazione DISIM - Dipartimento di Ingegneria e Scienze dell’Informazione e Matematiche Le classi interne (1) › Le classi interne (Inner classes), sono la soluzione che offre Java alle classi annidate › Offrono una maggiore chiarezza al programma e, come le interfacce, rappresentano una possibile soluzione al problema dell’eredità multipla Romina Eramo Tecnologie dei Linguaggi di Programmazione DISIM - Dipartimento di Ingegneria e Scienze dell’Informazione e Matematiche Creazione di classi interne (1) › E’ possibile dichiarare classi all’interno di un’altra classe › Esse possono avere qualsiasi modificatore di accesso » se una classe interna è dichiarata private, le sottoclassi delle classe esterna non possono vederla (viene tratta come se fosse un metodo) public class Esterna {! private int x;! public class Interna {! private int y;! public void metodoInterno(){! //...! }! }! }! Romina Eramo Tecnologie dei Linguaggi di Programmazione DISIM - Dipartimento di Ingegneria e Scienze dell’Informazione e Matematiche Creazione di classi interne (2) › I nomi completi delle classi sono Esterna ed Esterna.Interna ! › Per creare un’istanza della classe interna, se non dichiarata static, bisogna avere un’istanza della classe esterna, la creazione può avvenire nel seguente modo: Esterna.Interna a = new Esterna().new Interna();! › Se la classe interna è dichiarata static, è possibile creare un’istanza della stessa direttamente in questo modo: new Esterna.Interna ();! Romina Eramo Tecnologie dei Linguaggi di Programmazione DISIM - Dipartimento di Ingegneria e Scienze dell’Informazione e Matematiche Creazione di classi interne (3) › Le classi interne sembrano essere uguali a quelle normali a differenza del fatto che i nomi sono nidificati all’interno della classe esterna (Vedere Parcel1.java) › Tipicamente una classe esterna ha un metodo che restituisce un riferimento a una classe interna (Vedere Parcel2.java e metodi to() e contests()) Romina Eramo Tecnologie dei Linguaggi di Programmazione DISIM - Dipartimento di Ingegneria e Scienze dell’Informazione e Matematiche Collegamento alla classe esterna › Finora sembra che le classi interne siano una tecnica che occulta i nomi e lo schema di organizzazione del codice › C’è altro: » quando viene creata una classe interna, ogni suo oggetto possiede un collegamento all’oggetto esterno che lo ha creato, a cui si può accedere liberamente » le classi interne hanno diritti di accesso su tutti gli elementi della classe esterna (Vedere Sequence.java) Romina Eramo Tecnologie dei Linguaggi di Programmazione DISIM - Dipartimento di Ingegneria e Scienze dell’Informazione e Matematiche Utilizzo di .this e .new › Per generare un riferimento all’oggetto della classe esterna si indica: Esterna.this! (Vedere DotThis.java) ! › Un oggetto può creare un oggetto di una delle sue classi interne Estena e = new Esterna();! Esterna.Interna ei = e.new Interna();! (Vedere DotNew.java, Parcel3.java) Romina Eramo Tecnologie dei Linguaggi di Programmazione DISIM - Dipartimento di Ingegneria e Scienze dell’Informazione e Matematiche Classi interne e upcasting › Eseguire l’upcasting a una classe base, e in particolare ad un intefaccia › La classe interna (ovvero l’implementazione dell’interfaccia) può essere resa invisibile e non disponibile › Tutto ciò che si ottiene è un riferimento alla classe base o all’interfaccia (Vedere Destination.java, Contents.java, TestParcel.java) Romina Eramo Tecnologie dei Linguaggi di Programmazione DISIM - Dipartimento di Ingegneria e Scienze dell’Informazione e Matematiche Classi interne: metodi e ambiti › Le classi interne possono essere create anche all’interno di un metodo o di un ambito arbitrario › Motivazioni: » l’implementazione di un’interfaccia di qualsiasi tipo che permetta di creare e restituire un riferimento » la risoluzione di un problema complesso che richieda la creazione di una classe di supporto, che tuttavia non volete rendere disponibile (Vedere Parcel5.java (nidificazione in un metodo) (Vedere Parcel6.java (nidificazione in un ambito) Romina Eramo Tecnologie dei Linguaggi di Programmazione DISIM - Dipartimento di Ingegneria e Scienze dell’Informazione e Matematiche Classi interne locali (1) › Se la classe interna è scritto all’interno di un metodo viene chiamata classe interna locale › Come accade per gli attributi, essendo locali, non possono avere modificatori di accesso (tranne abstract e final) › Questo tipo di classi possono utilizzare solo gli elementi marcati final del metodo che la include, oltre a quelli della classe esterna Romina Eramo Tecnologie dei Linguaggi di Programmazione DISIM - Dipartimento di Ingegneria e Scienze dell’Informazione e Matematiche Classi interne locali (2) public class Esterna {! private int x = 0;! public int y = 0;! public void metodo(int a, final int b) { int c = a; final int d = a + b;! class Interna { public void metodoInterno() { System.out.println("x=" + x); System.out.println("y=" + y); System.out.println("a=" + a); System.out.println("b=" + b); System.out.println("c=" + c); System.out.println("d=" + d); } } Interna punt = new Interna(); punt.metodo(); } }! Romina Eramo Tecnologie dei Linguaggi di Programmazione // // // // // // Ok, è esterna Ok, è esterna Illegale, non Ok, è marcato Illegale, non Ok, è marcato alla classe interna alla classe interna è marcata final final è marcata final final DISIM - Dipartimento di Ingegneria e Scienze dell’Informazione e Matematiche Classi interne anonime › Java fornisce la possibilità di sovrapporre qualche metodo di una superclasse, o di implementare qualche metodo di un’interfaccia, senza dover costruire una classe vera e propria che lo faccia class A {! public void f() {! System.out.println("A");! }! }! ! class B { A a = new A() { public void f() { System.out.println("B"); } }; // notare il ’;’ }! Romina Eramo Tecnologie dei Linguaggi di Programmazione Come se il programmatore iniziasse a creare un oggetto A ma prima di arrivare al ; cambiasse idea decidendo di introdurre una definizione di classe (Vedere Parcel7.java) DISIM - Dipartimento di Ingegneria e Scienze dell’Informazione e Matematiche Perchè utilizzare classi interne? (1) › Non è sempre possibile lavorare con le interfacce, talvolta occorre lavorare con le implementazioni › Ogni classe interna può ereditare indipendentemente da un’implementazione. Di conseguenza la classe interna non è limitata dal fatto che la classe esterna stia già ereditando da un’implementazione › Le classi interne consentono di ereditare da più entità “non-interfaccia” (Vedere MultiInterfaces.java, MultiImplementation.java) Romina Eramo Tecnologie dei Linguaggi di Programmazione DISIM - Dipartimento di Ingegneria e Scienze dell’Informazione e Matematiche Perchè utilizzare classi interne? (2) › Se ad esempio si dispone di due interfacce da implementare all’interno di una classe, sono possibili due alternative: » creare una singola classe » creare una classe interna › In assenza di vincoli, la scelta di una delle due alternative non fa differenza dal punto di vista dell’implementazione (Vedere MultiInterfaces.java) Romina Eramo Tecnologie dei Linguaggi di Programmazione DISIM - Dipartimento di Ingegneria e Scienze dell’Informazione e Matematiche Perchè utilizzare classi interne? (3) › Se vengono utilizzate classi reali o abstract invece delle interfacce, si è vincolati all’utilizzo di classi interne qualora una terza classe debba implementare entrambe le altre › Le classi interne risolvono così il problema dell’ ereditarietà di implementazione multipla (Vedere MultiImplementation.java) Romina Eramo Tecnologie dei Linguaggi di Programmazione DISIM - Dipartimento di Ingegneria e Scienze dell’Informazione e Matematiche Perchè utilizzare classi interne? (4) › La classe interna può avere istanze multiple (ognuna con il proprio stato) indipendenti da quelle dell’oggetto di classe esterna › Una classe esterna può avere numerose classi interne, ognuna delle quali implementa la stessa interfaccia o eredita dalla stessa classe in modo diverso › Il punto di creazione della classe interna non è legato alla creazione dell’oggetto di classe esterna › Non si corre il rischio di confondere la relazione “è-un” con la classe interna perchè si tratta di entità separate Romina Eramo Tecnologie dei Linguaggi di Programmazione DISIM - Dipartimento di Ingegneria e Scienze dell’Informazione e Matematiche