Java - Classi interne

In questo capitolo, discuteremo delle classi interne di Java.

Classi annidate

In Java, proprio come i metodi, anche le variabili di una classe possono avere un'altra classe come membro. La scrittura di una classe all'interno di un'altra è consentita in Java. La classe scritta all'interno è chiamatanested classe la classe che contiene la classe interna è chiamata outer class.

Syntax

Di seguito è riportata la sintassi per scrivere una classe nidificata. Ecco, la classeOuter_Demo è la classe esterna e la classe Inner_Demo è la classe annidata.

class Outer_Demo {
   class Inner_Demo {
   }
}

Le classi annidate sono divise in due tipi:

  • Non-static nested classes - Questi sono i membri non statici di una classe.

  • Static nested classes - Questi sono i membri statici di una classe.

Classi interne (classi annidate non statiche)

Le classi interne sono un meccanismo di sicurezza in Java. Sappiamo che una classe non può essere associata al modificatore di accessoprivate, ma se abbiamo la classe come membro di un'altra classe, la classe interna può essere resa privata. E questo viene utilizzato anche per accedere ai membri privati ​​di una classe.

Le classi interne sono di tre tipi a seconda di come e dove le definisci. Sono -

  • Classe interna
  • Classe interna metodo-locale
  • Classe interna anonima

Classe interna

Creare una classe interna è abbastanza semplice. Hai solo bisogno di scrivere una classe all'interno di una classe. A differenza di una classe, una classe interna può essere privata e una volta dichiarata privata una classe interna, non è possibile accedervi da un oggetto esterno alla classe.

Di seguito è riportato il programma per creare una classe interna e accedervi. Nell'esempio fornito, rendiamo privata la classe interna e accediamo alla classe tramite un metodo.

Example

class Outer_Demo {
   int num;
   
   // inner class
   private class Inner_Demo {
      public void print() {
         System.out.println("This is an inner class");
      }
   }
   
   // Accessing he inner class from the method within
   void display_Inner() {
      Inner_Demo inner = new Inner_Demo();
      inner.print();
   }
}
   
public class My_class {

   public static void main(String args[]) {
      // Instantiating the outer class 
      Outer_Demo outer = new Outer_Demo();
      
      // Accessing the display_Inner() method.
      outer.display_Inner();
   }
}

Qui puoi osservarlo Outer_Demo è la classe esterna, Inner_Demo è la classe interiore, display_Inner() è il metodo all'interno del quale stiamo istanziando la classe interna e questo metodo viene richiamato dal main metodo.

Se compili ed esegui il programma sopra, otterrai il seguente risultato:

Output

This is an inner class.

Accesso ai membri privati

Come accennato in precedenza, le classi interne vengono utilizzate anche per accedere ai membri privati ​​di una classe. Supponiamo che una classe abbia membri privati ​​per accedervi. Scrivici una classe interna, restituisci i membri privati ​​da un metodo all'interno della classe interna, ad esempio,getValue()e infine da un'altra classe (dalla quale si desidera accedere ai membri privati) chiamare il metodo getValue () della classe interna.

Per istanziare la classe interna, inizialmente devi istanziare la classe esterna. Successivamente, utilizzando l'oggetto della classe esterna, segue il modo in cui è possibile istanziare la classe interna.

Outer_Demo outer = new Outer_Demo();
Outer_Demo.Inner_Demo inner = outer.new Inner_Demo();

Il seguente programma mostra come accedere ai membri privati ​​di una classe utilizzando la classe interna.

Example

class Outer_Demo {
   // private variable of the outer class
   private int num = 175;  
   
   // inner class
   public class Inner_Demo {
      public int getNum() {
         System.out.println("This is the getnum method of the inner class");
         return num;
      }
   }
}

public class My_class2 {

   public static void main(String args[]) {
      // Instantiating the outer class
      Outer_Demo outer = new Outer_Demo();
      
      // Instantiating the inner class
      Outer_Demo.Inner_Demo inner = outer.new Inner_Demo();
      System.out.println(inner.getNum());
   }
}

Se compili ed esegui il programma sopra, otterrai il seguente risultato:

Output

This is the getnum method of the inner class: 175

Classe interna metodo-locale

In Java, possiamo scrivere una classe all'interno di un metodo e questo sarà un tipo locale. Come le variabili locali, l'ambito della classe interna è limitato all'interno del metodo.

Una classe interna locale del metodo può essere istanziata solo all'interno del metodo in cui è definita la classe interna. Il seguente programma mostra come utilizzare una classe interna locale al metodo.

Example

public class Outerclass {
   // instance method of the outer class 
   void my_Method() {
      int num = 23;

      // method-local inner class
      class MethodInner_Demo {
         public void print() {
            System.out.println("This is method inner class "+num);	   
         }   
      } // end of inner class
	   
      // Accessing the inner class
      MethodInner_Demo inner = new MethodInner_Demo();
      inner.print();
   }
   
   public static void main(String args[]) {
      Outerclass outer = new Outerclass();
      outer.my_Method();	   	   
   }
}

Se compili ed esegui il programma sopra, otterrai il seguente risultato:

Output

This is method inner class 23

Classe interna anonima

Una classe interna dichiarata senza un nome di classe è nota come anonymous inner class. In caso di classi interne anonime, le dichiariamo e le istanziamo allo stesso tempo. In genere, vengono utilizzati ogni volta che è necessario sovrascrivere il metodo di una classe o di un'interfaccia. La sintassi di una classe interna anonima è la seguente:

Syntax

AnonymousInner an_inner = new AnonymousInner() {
   public void my_method() {
      ........
      ........
   }   
};

Il seguente programma mostra come sovrascrivere il metodo di una classe utilizzando la classe interna anonima.

Example

abstract class AnonymousInner {
   public abstract void mymethod();
}

public class Outer_class {

   public static void main(String args[]) {
      AnonymousInner inner = new AnonymousInner() {
         public void mymethod() {
            System.out.println("This is an example of anonymous inner class");
         }
      };
      inner.mymethod();	
   }
}

Se compili ed esegui il programma sopra, otterrai il seguente risultato:

Output

This is an example of anonymous inner class

Allo stesso modo, puoi sovrascrivere i metodi della classe concrete e dell'interfaccia utilizzando una classe interna anonima.

Classe interna anonima come argomento

Generalmente, se un metodo accetta un oggetto di un'interfaccia, una classe astratta o una classe concreta, allora possiamo implementare l'interfaccia, estendere la classe astratta e passare l'oggetto al metodo. Se è una classe, possiamo passarla direttamente al metodo.

Ma in tutti e tre i casi, puoi passare una classe interna anonima al metodo. Ecco la sintassi per passare una classe interna anonima come argomento del metodo:

obj.my_Method(new My_Class() {
   public void Do() {
      .....
      .....
   }
});

Il seguente programma mostra come passare una classe interna anonima come argomento del metodo.

Example

// interface
interface Message {
   String greet();
}

public class My_class {
   // method which accepts the object of interface Message
   public void displayMessage(Message m) {
      System.out.println(m.greet() +
         ", This is an example of anonymous inner class as an argument");  
   }

   public static void main(String args[]) {
      // Instantiating the class
      My_class obj = new My_class();

      // Passing an anonymous inner class as an argument
      obj.displayMessage(new Message() {
         public String greet() {
            return "Hello";
         }
      });
   }
}

Se compili ed esegui il programma sopra, ottieni il seguente risultato:

Output

Hello, This is an example of anonymous inner class as an argument

Classe annidata statica

Una classe interna statica è una classe annidata che è un membro statico della classe esterna. È possibile accedervi senza creare un'istanza della classe esterna, utilizzando altri membri statici. Proprio come i membri statici, una classe annidata statica non ha accesso alle variabili di istanza e ai metodi della classe esterna. La sintassi della classe annidata statica è la seguente:

Syntax

class MyOuter {
   static class Nested_Demo {
   }
}

Istanziare una classe annidata statica è un po 'diverso dall'istanziare una classe interna. Il programma seguente mostra come utilizzare una classe annidata statica.

Example

public class Outer {
   static class Nested_Demo {
      public void my_method() {
         System.out.println("This is my nested class");
      }
   }
   
   public static void main(String args[]) {
      Outer.Nested_Demo nested = new Outer.Nested_Demo();	 
      nested.my_method();
   }
}

Se compili ed esegui il programma sopra, otterrai il seguente risultato:

Output

This is my nested class