Interfacce notevoli
-
Comparable
- Impone un ordinamento naturale degli oggetti tramite il metodo: int
compareTo(T b)
, che restituisce un valore >, = o < 0 se l’oggetto è rispettivamente maggiore, uguale o minore di b (T è un tipo generico; può essere qualsiasi tipo)
- Impone un ordinamento naturale degli oggetti tramite il metodo: int
-
Clonabile
- Le classi che implementano quest’interfaccia dichiarano al metodo
clone()
di Object che è legale effettuare una copia campo-a-campo delle istanze della classe - Il metodo
clone()
invocato su oggetti di classi che non implementanoCloneable
solleva unaCloneNotSupportedException
- Le classi che implementano quest’interfaccia dichiarano al metodo
-
Serializzabile
- Quest’interfaccia non possiede metodi o campi e serve soltanto ad identificare il fatto che l’oggetto è serializzabile, cioè memorizzabile su un certo supporto
Passare funzioni in input mediante le interfacce
- Le interfacce permettono il passaggio in input di funzioni con una determinata intestazione
Ex.
public interface Runnable
{
void run()
}
Le enumerazioni possono estendere interfacce
- Posso rendere le enumerazioni estendibili quanto voglio
public interface OperatoreBinario
{
double applica(double a, double b);
}
public enum OperatoreDiBase implements OperatoreBinario
{
SOMMA {public double applica (double a, double b) {return a+b}}
}
Sovrascrivere il metodi clone
-
L’operatore di assegnazione
=
non effettua una copia dell’oggetto, ma solo del riferimento (shallow copy) -
Per creare una copia di un oggetto è necessario richiamare
clone()
(deep copy) -
x.clone() != x
sarĂ sempre vero -
clone
non richiama il costruttore della classe -
Tuttavia l’implementazione nativa di default id
Object.clone
copia l’oggetto campo per campo- Ottimo se i campi sono tutti primitivi
- Problematico se i campi sono riferimenti
-
Per implementare la copia in una propria classe è necessario sovrascrivere
clone()
che è protetta (quindi visibile solo in gerarchia e nel package)- Se il nostro oggetto contiene riferimenti e vogliamo evitare che la copia contenga un riferimento allo stesso oggetto membro, non possiamo chiamare semplicemente (o non chiamiamo proprio)
super.clone()
- Se il nostro oggetto contiene riferimenti e vogliamo evitare che la copia contenga un riferimento allo stesso oggetto membro, non possiamo chiamare semplicemente (o non chiamiamo proprio)
-
E’ necessario implementare l’interfaccia “segnaposto”
Cloneable
altrimentiObject.clone
emetterà semplicemente l’eccezioneCloneNotSupportedException
Classi top-level
- Le classi usate finora sono dette top-level perché si trovano in alto rispetto a tutte le altre
- Questo tipo di classi richiede un file .java dedicato con lo stesso nome della classe che esso contiene
Classi annidate (nested class)
- Java consente di scrivere classi all’interno di altre classi
- Le classi presenti all’interno sono chiamate classi annidate (nested class)
- Possono essere static
- Oppure non-static: in questo caso vengono dette classi interne (inner class)
Classi interne
-
Per poter creare un oggetto della casse interna è necessario istanziare la classe esterna (top-level) che la contiene
-
Ciascuna classe interna, infatti, ha un riferimento implicito all’oggetto della classe cha la contiene
-
Dalla classe interna è possibile accede a tutte le variabili e a tutti metodi della classe esterna
-
Come tutti i membri di una classe, le classi interne possono essere dichiarate public, protected o private
-
L’accesso a campi e metodi sia dell’oggetto della classe interna che dell’oggetto della classe esterna a cui è legato a doppio filo avviene normalmente
-
Per disambiguare casi di ambiguitĂ (es. campi con lo stesso nome nella classe interna ed esterna):
- Se dalla classe interna viene usato soltanto this si fa riferimento ai campi e ai metodi di quella classe
- Per far riferimento alla classe esterna è necessario far precedere this dal nome della classe esterna e il punto
-
Per istanziare la classe interna dalla classe esterna è sufficiente utilizzare l’operatore new
-
Per istanziare la classe interna a partire da un’altra classe si utilizza la sintassi
riferimentoOggettoClasseEsterna.new ClasseInterna()
Classi anonime
- Sono classi senza nome che implementano un’intefaccia o estendono una classe
- Utilizzate esclusivamente per creare un’unica istanza
- Utili in determinati contesti (ex. creare un iteratore al volo)Ăą
TipoDaEstedere unicoRiferimentoAOggetto = new TipoDaEstendere()
{
//codice della classe anonima (implementazione
// dell'interfaccia o dell'estsione della classe)
}
Espressioni lambda
() -> {System.out.printl ("hello, lambda!");}
- Tali espressioni creano oggetti anonimi assegnabili a riferimenti a interfacce funzionali compatibili con l’intestazione (input/output) della funzione creata
Runnable r = () -> {System.out.println("hello, lambda!");};
r.run(); //"stampa hello lambda!"