CodeGym /Java Blog /Random-IT /Classi interne Java
John Squirrels
Livello 41
San Francisco

Classi interne Java

Pubblicato nel gruppo Random-IT
In Java alcune classi possono contenere altre classi al loro interno. Tali classi sono chiamate classi nidificate. Le classi definite all'interno di altre classi generalmente rientrano in due categorie: statiche e non statiche. Le classi non statiche nidificate sono chiamate interne. Le classi nidificate dichiarate statiche sono chiamate classi nidificate statiche. In realtà, qui non c'è nulla di complicato, anche se la terminologia sembra un po' confusa e talvolta può confondere anche uno sviluppatore di software professionista.

Classi nidificate e interne

Quindi tutte le classi situate all'interno di altre classi sono chiamate classi nidificate.
class OuterClass {
    ...
    class NestedClass {
        ...
    }
}
Le classi nidificate che non sono statiche sono chiamate classi interne e quelle che sono statiche sono chiamate classi nidificate statiche . Classi interne Java - 1
class OuterClass {
    ...
    static class StaticNestedClass {
        ...
    }
    class InnerClass {
        ...
    }
}
Pertanto, tutte le classi interne sono annidate, ma non tutte le classi annidate sono interne. Queste le principali definizioni. Le classi interne sono una sorta di meccanismo di sicurezza in Java. Sappiamo che una classe ordinaria non può essere associata a un modificatore di accesso privato. Tuttavia, se la nostra classe è membro di un'altra classe, allora la classe interna può essere resa privata. Questa funzionalità viene utilizzata anche per accedere ai membri della classe privata.

Esempio di classe interna

Quindi, proviamo a creare una classe e al suo interno un'altra classe. Immagina una sorta di console di gioco modulare. C'è una "scatola" stessa e alcuni moduli possono essere collegati ad essa. Ad esempio, un controller di gioco, un volante, un casco VR, che, di regola, non funzionano senza la console stessa. Qui abbiamo la classe GameConsole. Ha 2 campi e 1 metodo: start() . La differenza tra GameCosole e la classe a cui siamo abituati è che ha una classe GameController interna .
public class GameConsole {
    private String model;
    private int weight;

    public void run() {
        System.out.println("Game console is on");
    }


    public class GameController {

        private String color;

        public void start() {
            System.out.println("start button is pressed");
        }

        public void x() {
            System.out.println("x button is pressed");
        }

        public void y() {
            System.out.println("y button is pressed");
        }
        public void a() {
            System.out.println("a button is pressed");
        }

        public void b() {
            System.out.println("b button is pressed");
        }
        public void mover() {
            System.out.println("mover button is pressed");
        }

    }

}
A questo punto vi starete chiedendo: perché non rendere queste classi “separate”? Non è necessario farli annidare. In effetti è possibile. Si tratta piuttosto della corretta progettazione delle classi in termini di utilizzo. Le classi interne vengono create per evidenziare nel programma un'entità che è indissolubilmente legata ad un'altra entità. Un controller o, ad esempio, un casco VR sono componenti della console. Sì, possono essere acquistati separatamente dalla console, ma non possono essere utilizzati senza di essa. Se rendessimo tutte queste classi classi pubbliche separate, il nostro programma potrebbe avere, ad esempio, il seguente codice:
public class Main {

   public static void main(String[] args) {
       GameController controller = new GameController();
       controller.x();
   }
}
Ciò che accade in questo caso non è chiaro, dal momento che il controller stesso non funziona senza una console. Abbiamo creato un oggetto console di gioco. Abbiamo creato il suo sottooggetto: il controller di gioco. E ora possiamo giocare, basta premere i tasti giusti. I metodi di cui abbiamo bisogno vengono chiamati sugli oggetti giusti. Tutto è semplice e conveniente. In questo esempio, l'estrazione del controller di gioco migliora l'incapsulamento (nascondiamo i dettagli delle parti della console all'interno della classe corrispondente) e consente un'astrazione più dettagliata. Ma se, ad esempio, creiamo un programma che simuli un negozio in cui è possibile acquistare separatamente un casco o un controller VR, questo esempio fallirà. Lì è meglio creare un controller di gioco separatamente. Facciamo un altro esempio. Abbiamo menzionato sopra che possiamo rendere privata la classe interna e chiamarla comunque dalla classe esterna. Di seguito è riportato un esempio di tali classi.
class OuterClass {

   // inner class
   private class InnerClass {
       public void print() {
           System.out.println("We are in the inner class...");
       }
   }

   // method of outer class. We are create an inner class from the method of outer one
   void display() {
       InnerClass inner = new InnerClass();
       inner.print();
   }
}
Qui OuterClass è la classe esterna, InnerClass è la classe interna, display() è il metodo all'interno del quale stiamo creando un oggetto della classe interna. Ora scriviamo una classe demo con un metodo main in cui invocheremo il metodo display() .
public class OuterDemoMain {

       public static void main(String args[]) {
           // create an object of the outer class
           OuterDemo outer = new OuterDemo();

           outer.display();
       }
}
Se esegui questo programma, otterrai il seguente risultato:
Siamo nella classe interna...

Classificazione delle classi interne

Le classi interne stesse o le classi non statiche annidate si dividono in tre gruppi.
  • Classe interiore così com'è. Solo una classe non statica all'interno dell'altra, come abbiamo dimostrato sopra con l'esempio di GameConsole e GameController .
  • La classe interna locale al metodo è una classe all'interno di un metodo.
  • Classe interna anonima.
Classi interne Java - 2

Metodo locale Classe interna

In Java puoi scrivere una classe all'interno di un metodo ed è un tipo locale. Come le variabili locali, l'ambito di una classe interna è limitato all'interno di un metodo. Una classe interna locale al metodo può essere creata solo all'interno del metodo in cui è definita la classe interna. Dimostriamo come utilizzare la classe interna del metodo locale.
public class OuterDemo2 {

   //instance method of the outer class OuterDemo2
   void myMethod() {
       String str = "and it's a value from OuterDemo2 class' myMethod ";

       // method-local inner class
       class methodInnerDemo {
           public void print() {
               System.out.println("Here we've got a method inner class... " );
               System.out.println(str);

           }
       }

       // Access to the inner class
       methodInnerDemo inn = new methodInnerDemo();
       inn.print();
   }
}
Ora scriveremo una classe demo con un metodo main in cui invocheremo il metodo outside() .
public class OuterDemoMain {


   public static void main(String args[]) {
       OuterDemo2 outer = new OuterDemo2();
       outer.myMethod();
   }
}
L'output è:
Qui abbiamo un metodo classe interna... ed è un valore da myMethod della classe OuterDemo2

Classe interna anonima

Una classe interna dichiarata senza un nome di classe è chiamata classe interna anonima. Quando dichiariamo una classe interna anonima, la istanziamo immediatamente. In genere, tali classi vengono utilizzate ogni volta che è necessario sovrascrivere una classe o un metodo di interfaccia.
abstract class OuterDemo3 {
   public abstract void method();

}
   class outerClass {

       public static void main(String args[]) {
           OuterDemo3 inner = new OuterDemo3() {
               public void method() {
                   System.out.println("Here we've got an example of an  anonymous inner class");
               }
           };
           inner.method();
       }
   }
L'output è qui:
Qui abbiamo un esempio di classe interna anonima...

Classe interna anonima come argomento

Puoi anche passare una classe interna anonima come argomento al metodo. Ecco un esempio.
interface OuterDemo4 {
       String hello();
   }

   class NewClass {
       // accepts the object of interface
       public void displayMessage(OuterDemo4 myMessage) {
           System.out.println(myMessage.hello());
           System.out.println("example of anonymous inner class as an argument");
       }

       public static void main(String args[]) {
           NewClass newClass = new NewClass();

           //here we pass an anonymous inner class as an argument
           newClass.displayMessage(new OuterDemo4() {
               public String hello() {
                   return "Hello!";
               }
           });
       }
}
L'output è qui:
Ciao! esempio di classe interna anonima come argomento
Per rafforzare ciò che hai imparato, ti suggeriamo di guardare una lezione video dal nostro corso Java
Commenti
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION