Classe interna
Nella programmazione orientata agli oggetti (OOP, Object Oriented Programming) una classe interna (dall'inglese classe nidificata o una classe interna) è una classe dichiarata all'interno di un'altra classe o classe di interfaccia. Si trovano in linguaggi come Java, a partire dalla versione 1.1, o D. In Python, è possibile creare una classe interna all'interno di una classe, metodo o funzione.
Generalità
[modifica | modifica wikitesto]Un'istanza di una normale o principale classe può esistere da sola. Invece, un'istanza di una classe interna, non può essere istanziata senza essere collegata con una classe principale.
Prendiamo come una nozione astratta una Macchina
con quattro Ruote
. Le nostre Ruote
hanno caratteristiche specifiche che dipendono dall'essere parte della nostra Macchina
. Questo concetto non rappresenta le Ruote
come Ruote
in generale, che possono essere parte di un veicolo, le rappresenta invece in modo specifico. Possiamo modellare questo concetto usando le classi interne come segue:
Abbiamo la classe principale Macchina
. Le istanze della classe Macchina
sono composte da quattro istanze della classe Ruote
. Questa particolare implementazione di Ruote
è specifica per la macchina, così il codice non modella il generale concetto di ruota che può essere meglio rappresentato come una classe principale. Quindi è semanticamente connessa alla classe Macchina
e il codice di Ruote
è in qualche modo accoppiato alla classe esterna. La ruota è più unita alla macchina. La ruota per una particolare macchina è unica, mentre per la ruota in generale è unita in aggregazione alla macchina. Noi diciamo che le nostre Ruote
sono nella classe Macchina
.
Le classi interne ci forniscono un meccanismo per modellare accuratamente questa connessione. Ruote
, Macchina
essendo la classe principale e Ruote
essendo la classe interna.
Le classi interne pertanto riguardano l'orientamento dell'oggetto di alcune parti del programma che non sarebbero altrimenti incapsulate in una classe.
Grandi pezzi di codice all'interno di una classe potrebbero essere modellati o riscritti come una separata classe principale piuttosto di una classe interna. Ciò rende il codice più generale nella sua applicazione e quindi riusabile ma potrebbe potenzialmente essere una prematura generalizzazione. Può risultare più efficace, se il codice ha molte classi interne con la funzionalità condivisa.
I tipi delle classi interne
[modifica | modifica wikitesto]In Java esistono molti tipi di classi interne che si divido in quattro differenti gruppi:
- Classi (ed interfacce) statiche innestate.
- Classi membro.
- Classi locali.
- Classi anonime.
Le classi statiche in Java
[modifica | modifica wikitesto]Le classi interne dichiarate con la parola chiave static, funzionano come le comuni classi statiche; non sono collegate ad un'istanza ma possono accedere solo alle variabili e ai metodi statici della classe contenitrice. I tipi esterni dovevano anteporre al nome della classe interna quello della classe contenitrice. Le classi interne sono implicitamente statiche.
/*Classe contenitrice */
public class ClasseContenitrice
{
private static String variableStatica = "variable statica";
// Costruttore della classe contenitrice
public ClasseContenitrice()
{
}
//Metodo statico che può richiamare la classe interna statica
public static void staticMetodo(){
InterfacciaInterna ic = new ClasseInterna();
ic.stampa();
}
//Classe interna statica
private static class ClasseInterna implements InterfacciaInterna
{
//Costruttore della classe interna statica
public ClasseInterna()
{
}
/*Implementazione della classe interna
* Richiamare la variabile statica dalla classe contenente*/
public void stampa(){
System.out.println(variabileStatica);
}
}
//Interfaccia interna (implicitamente statica)
private interface InterfacciaInterna{
public void stampa();
}
}
Ogni istanza di una classe interna si riferisce ad un'istanza della classe contenitrice, fatta eccezione per le classi interne locali e le classi anonime dichiarate in un contesto statico. Pertanto, esse possono implicitamente fare riferimento a variabili e metodi della classe contenitrice dell'istanza. Il riferimento della classe interna all' istanza può essere ottenuto tramite NomeDellaClasseContenitrice.this.
Tuttavia, una classe interna non può contenere variabili o metodi statici. Al suo inizio, deve essere riportato un riferimento alla classe contenitrice, ciò significa che non ci può essere un'istanza in un metodo di istanza o in un costruttore della classe contenitrice, o (per i membri delle classi e delle classi anonime) utilizzando la sintassi instanceContenitrice.new ClasseInterna
().