Sobes.tech
Middle

Quali sono i tipi di classi annidate?

sobes.tech AI

Risposta dell'AI

Le classi annidate (Nested Classes) in Java si dividono in due tipi principali:

  1. Classi annidate statiche (Static Nested Classes)

    • Contrassegnate con il modificatore static.
    • Si comportano come normali membri statici della classe contenitore.
    • Possono accedere ai membri statici della classe esterna (anche se privati).
    • Non hanno accesso diretto ai membri non statici della classe esterna.
    • Vengono create senza un'istanza della classe esterna: OuterClass.StaticNestedClass nestedObject = new OuterClass.StaticNestedClass();.
  2. Classi interne (Inner Classes)

    Le classi interne non sono contrassegnate con static e sono legate a un'istanza della classe esterna. Si suddividono in:

    • Classi membro (Member Inner Classes)

      • Sono dichiarate a livello di membro della classe contenitore, ma fuori dai suoi metodi.
      • Hanno accesso a tutti i membri della classe esterna, inclusi quelli privati.
      • Richiedono un'istanza della classe esterna per creare la propria istanza: OuterClass outerObject = new OuterClass(); OuterClass.MemberInnerClass innerObject = outerObject.new MemberInnerClass();.
    • Classi locali (Local Classes)

      • Sono create all'interno di metodi, costruttori o blocchi di inizializzazione.
      • La loro visibilità è limitata al blocco in cui sono dichiarate.
      • Non possono essere dichiarate con modificatori di accesso (public, private, protected).
      • Possono accedere a variabili locali finali o effettivamente finali del blocco esterno.
      • Non possono essere usate al di fuori del blocco in cui sono definite.
    • Classi anonime (Anonymous Classes)

      • Sono, in sostanza, classi locali senza nome.
      • Sono dichiarate e istanziate contemporaneamente.
      • Sono usate per implementare una classe astratta o un'interfaccia "al volo".
      • Come le classi locali, hanno accesso a variabili locali finali o effettivamente finali del blocco esterno.

Esempio di struttura:

class OuterClass {
    private int outerField;
    private static int staticOuterField;

    // Classe annidata statica
    static class StaticNestedClass {
        void accessOuter() {
            // Può accedere ai membri statici della classe esterna
            int value = staticOuterField;
            // Non può accedere ai membri non statici
            // int value2 = outerField; // Errore di compilazione
        }
    }

    // Classe membro (classe interna)
    class MemberInnerClass {
        void accessOuter() {
            // Può accedere a tutti i membri della classe esterna
            int value1 = outerField;
            int value2 = staticOuterField;
        }
    }

    void methodWithLocalAndAnonymous() {
        final int localVar = 10; // final o effettivamente finale

        // Classe locale
        class LocalClass {
            void accessOuter() {
                // Può accedere ai membri della classe esterna e variabili locali finali/effettivamente finali
                int value1 = outerField;
                int value2 = staticOuterField;
                int localValue = localVar;
            }
        }

        LocalClass localObj = new LocalClass();
        localObj.accessOuter();

        // Classe anonima (che implementa Runnable)
        Runnable anonymousRunnable = new Runnable() {
            @Override
            public void run() {
                // Può accedere ai membri della classe esterna e variabili locali finali/effettivamente finali
                int value1 = outerField;
                int value2 = staticOuterField;
                int localValue = localVar;
                System.out.println("Esecuzione con variabile locale: " + localValue);
            }
        };

        anonymousRunnable.run();
    }
}