Nested Classes
Static nested classes
Il nome completo della nested class è WireFrameModel.Line
. Questo nome può essere utilizzato ad esempio per dichiarare le variabili. All'interno di WireFramaModel un oggetto di tipo Line, sarebbe dichiarato con new Line()
. All'esetno della classe contenitore con new WireFrameModel.Line()
.
Una static nested class, ha accesso completo ai membri statici della classe contenitore, anche se sono membri privati.
Inner class
Una nested class non static, è chiamata una inner class. Una Inner class, non è in pratica molto differente da una nested class, ma una non-static nested class è associata con un oggetto piuttosto che con la classe al cui interno è definita.
I membri non statici di una classe specificano cosa verrà contenuto negli oggetti che sono creati dalla classe. Lo stesso è vero per le inner class. Cioè ogni oggetto che appartiene alla classe contenitore ha la sua copia della nested class. Questa classe ha accesso a tutti i membri e metodi d'istanza dell'oggetto anche se sono dichiarati private
. Le due copie dell'inner class in due oggetti differenti differiscono perché le variabili d'istanza e i metodi d'istanza a cui si riferiscono sono in oggetti differenti. In effetti, la regola per decidere se una nested class, devono essere static o non-static è semplice: Se la nested class ha bisogno di accedere ai membri o metodi d'istanza della classe contenitore, creaimo la nested class, non-static. Altrimenti facciamola static.
Se game è una variabile di tipo PokerGame
, allora, concettualmente, game contiene la propria copia della classe Player
. In un metodo d'instanza di un oggetto di tipo PokerGame, un nuovo oggetto di tipo Player
, verrà creato con istruzione "new Player()", così come ogni altra classe. (Un oggetto invece Player, che volesse essere creato dall'esterno della classe PockerGame, utilizzo più raro, dovrebbe essere creato tramite l'istruzione "game.new Player()"). L'oggetto di tipo Player
avrebbe accesso alle variabili d'istanza deck e pot dell'oggetto di tipo PokerGame
. Ogni oggetto di tipo PokerGame
ha il proprio deck, pot e Players. I Player di quel particolare poker game, partita di poker, utilizzano il mazzo (deck) e puntata (pot) per quella particolare partita; giocatori di un altro poker game, partita, avranno un altro mazzo, deck, e puntata, pot. Questo è l'effetto di avere la classe Player
non-static. Questo è il modo naturale per i giocatori di comportarsi. Un oggetto di tipo Player
rappresenta un giocatore in una particolare partita di poker. Se Player fosse stata una classe indipendente o una classe statica, d'altro lato, essa avrebbe rappresentato l'idea generale di giocatore di poker, indipendentemente dalla particolare partita di poker.
Anonymous Inner classes
In alcuni casi, vi potresete trovare a scrivere un' inner class e a utilizzare quella classe in usa sol punto del vostro codice. Ha senso allora creare una classe? Può darsi, ma potreste anche creare un anomymous inner class. Un' anomymous inner class, è creata con una con una variazione dell'operatore new, che ha la forma:
Questo costruttore definisce una nuova classe senza assegnargli un nome. Questa forma dell'operatore new è creare "un nuovo oggetto appartenente a una classe che è la stessa come <superclass-or-interface> ma con questi <methods-and-variables> aggiunti. Il risultato è ottenere un oggetto unico customizzato, giusto nel punto del programma in cui è necessario. Da notare che è possibile basare una classe anonima su un'interfaccia, piuttosto che una classe. In questo caso, una classe anonima, deve implementare un'interfaccia definendo tutti i metodi che sono dichiarati nell'interfaccia. Se un'interfaccia è utilizzata come base, la <parameter-list> deve essere vuota. Altrimenti, può contenere i parametri del costruttore della <superclass>.
Supponiamo di avere un'interfaccia Drawable
così definita:
Se vogliamo utilizzare un oggetto di tipo Drawable di colore rosso che sia un rettangolo, invece di creare una nuova classe che implementi Drawable e poi instanziala per creare l'oggetto, possimo invece usare una classe anonima per creare l'oggetto direttamente.
La variabile redSquare riferisce a un oggetto che implementa Drawable
e che disegna un rettangolo rosso quando il metodo draw()
è invocato.
Una classe anonima è spesso utilizzata come parametri attuali. Per esempio considera questa funzione:
Quando chiamiamo questo metodo, il terzo parametro può essere creato utilizzano una classe anonima. Per esempio:
Local classes
Una classe può essere definita pure all'interno di un metodo. Queste classi cono chiamate local classes, classi locali. Una local class può essere solo utilizzata all'interno del metodo in cui è definita. Tuttavia un oggetto che è definito da una local class può essere utilizzato all'esterno del metodo. Può essere ritornato come valore di una subroutine, o può essere passato come parametro di un altro metodo. Questo è possibile, perché un oggetto appartenente a qualche classe B può essere assegnato a una variabile di tipo A, se B è sottoclasse di A o, se la classe B implementa l'interfaccia A. Ad esempio se un metodo accetta come parametro un oggetto di tipo Drawable
(interfaccia definita negli esempi sopra), allora un oggetto che implementa Drawable
può essere passato come parametro a quel metodo. E quell'oggetto può essere definito da una local class.
La definizione di una local class può utilizzare le variabili locali del metodo all'interno del quale è definita. Può utilizzare anche parametri di quel metodo. Tuttavia c'è una restrizione nell'utilizzo di queste variabili locali e parametri nella local class: Le variabili locali o i parametri devono essere dichiarati final o, se non esplicitamente dichiarati final, devono esser "effettivamente final". Un parametro è "effettivamente final" se il suo valore non è cambiato all'interno della subroutine (inclusa ogni local class che riferisce il parametro). Una variabile locale è "effettivamente final" se il suo valore non è mai cambiato dopo che viene inizializzata. Nota che non c'è una simile restrizione sulle variabili globali che sono usate nella definizione di una local class.
Last updated