Clase interna y anidada de Java (con ejemplos)

En este tutorial, aprenderá sobre la clase anidada en Java y sus tipos con la ayuda de ejemplos.

En Java, puede definir una clase dentro de otra clase. Tal clase se conoce como nested class. Por ejemplo,

 class OuterClass ( //… class NestedClass ( //… ) )

Hay dos tipos de clases anidadas que puede crear en Java.

  • Clase anidada no estática (clase interna)
  • Clase anidada estática

Lectura recomendada :

  • Modificadores de acceso a Java
  • Palabra clave estática de Java

Veamos primero las clases anidadas no estáticas.

Clase anidada no estática (clase interna)

Una clase anidada no estática es una clase dentro de otra clase. Tiene acceso a los miembros de la clase adjunta (clase externa). Se conoce comúnmente como inner class.

Dado que inner classexiste dentro de la clase externa, primero debe crear una instancia de la clase externa para crear una instancia de la clase interna.

Aquí tienes un ejemplo de cómo puedes declarar clases internas en Java.

Ejemplo 1: clase interior

 class CPU ( double price; // nested class class Processor( // members of nested class double cores; String manufacturer; double getCache()( return 4.3; ) ) // nested protected class protected class RAM( // members of protected nested class double memory; String manufacturer; double getClockSpeed()( return 5.5; ) ) ) public class Main ( public static void main(String() args) ( // create object of Outer class CPU CPU cpu = new CPU(); // create an object of inner class Processor using outer class CPU.Processor processor = cpu.new Processor(); // create an object of inner class RAM using outer class CPU CPU.RAM ram = cpu.new RAM(); System.out.println("Processor Cache = " + processor.getCache()); System.out.println("Ram Clock speed = " + ram.getClockSpeed()); ) )

Salida :

 Caché del procesador = 4,3 Ram Velocidad de reloj = 5,5

En el programa anterior, hay dos clases anidadas: Procesador y RAM dentro de la clase externa: CPU. Podemos declarar la clase interna protegida. Por lo tanto, hemos declarado que la clase RAM está protegida.

Dentro de la clase principal,

  • Primero creamos una instancia de una CPU de clase externa llamada cpu.
  • Usando la instancia de la clase externa, luego creamos objetos de clases internas:
     CPU.Processor processor = cpu.new Processor; CPU.RAM ram = cpu.new RAM();

Nota : Usamos el .operador punto ( ) para crear una instancia de la clase interna usando la clase externa.

Acceso a miembros de la clase externa dentro de la clase interna

Podemos acceder a los miembros de la clase externa usando esta palabra clave. Si desea obtener más información sobre esta palabra clave, visite Java this keyword.

Ejemplo 2: Acceso a miembros

 class Car ( String carName; String carType; // assign values using constructor public Car(String name, String type) ( this.carName = name; this.carType = type; ) // private method private String getCarName() ( return this.carName; ) // inner class class Engine ( String engineType; void setEngine() ( // Accessing the carType property of Car if(Car.this.carType.equals("4WD"))( // Invoking method getCarName() of Car if(Car.this.getCarName().equals("Crysler")) ( this.engineType = "Smaller"; ) else ( this.engineType = "Bigger"; ) )else( this.engineType = "Bigger"; ) ) String getEngineType()( return this.engineType; ) ) ) public class Main ( public static void main(String() args) ( // create an object of the outer class Car Car car1 = new Car("Mazda", "8WD"); // create an object of inner class using the outer class Car.Engine engine = car1.new Engine(); engine.setEngine(); System.out.println("Engine Type for 8WD= " + engine.getEngineType()); Car car2 = new Car("Crysler", "4WD"); Car.Engine c2engine = car2.new Engine(); c2engine.setEngine(); System.out.println("Engine Type for 4WD = " + c2engine.getEngineType()); ) )

Salida :

 Tipo de motor para 8WD = más grande Tipo de motor para 4WD = más pequeño

En el programa anterior, tenemos la clase interna llamada Engine dentro de la clase externa Car. Aquí, observe la línea,

 if(Car.this.carType.equals("4WD")) (… )

Estamos usando una thispalabra clave para acceder a la variable carType de la clase externa. Puede que hayas notado que en lugar de usar this.carTypehemos usado Car.this.carType.

Es porque si no hubiéramos mencionado el nombre de la clase externa Car, entonces la thispalabra clave representará al miembro dentro de la clase interna.

De manera similar, también estamos accediendo al método de la clase externa desde la clase interna.

 if (Car.this.getCarName().equals("Crysler") (… )

Es importante señalar que, aunque getCarName()es un privatemétodo, podemos acceder a él desde la clase interna.

Clase anidada estática

En Java, también podemos definir una staticclase dentro de otra clase. Tal clase se conoce como static nested class. Las clases anidadas estáticas no se denominan clases internas estáticas.

A diferencia de la clase interna, una clase anidada estática no puede acceder a las variables miembro de la clase externa. Es porque la clase anidada estática no requiere que cree una instancia de la clase externa.

 OuterClass.NestedClass obj = new OuterClass.NestedClass();

Aquí, estamos creando un objeto de la clase anidada estática simplemente usando el nombre de clase de la clase externa. Por lo tanto, no se puede hacer referencia a la clase externa usando OuterClass.this.

Ejemplo 3: Clase interna estática

 class MotherBoard ( // static nested class static class USB( int usb2 = 2; int usb3 = 1; int getTotalPorts()( return usb2 + usb3; ) ) ) public class Main ( public static void main(String() args) ( // create an object of the static nested class // using the name of the outer class MotherBoard.USB usb = new MotherBoard.USB(); System.out.println("Total Ports = " + usb.getTotalPorts()); ) )

Salida :

 Total de puertos = 3

En el programa anterior, hemos creado una clase estática llamada USB dentro de la clase MotherBoard. Note la línea,

 MotherBoard.USB usb = new MotherBoard.USB();

Aquí, estamos creando un objeto de USB usando el nombre de la clase externa.

Ahora, veamos qué pasaría si intenta acceder a los miembros de la clase externa:

Ejemplo 4: acceder a miembros de la clase externa dentro de la clase interna estática

 class MotherBoard ( String model; public MotherBoard(String model) ( this.model = model; ) // static nested class static class USB( int usb2 = 2; int usb3 = 1; int getTotalPorts()( // accessing the variable model of the outer classs if(MotherBoard.this.model.equals("MSI")) ( return 4; ) else ( return usb2 + usb3; ) ) ) ) public class Main ( public static void main(String() args) ( // create an object of the static nested class MotherBoard.USB usb = new MotherBoard.USB(); System.out.println("Total Ports = " + usb.getTotalPorts()); ) )

Cuando intentemos ejecutar el programa, obtendremos un error:

 error: variable no estática, no se puede hacer referencia a esto desde un contexto estático

This is because we are not using the object of the outer class to create an object of the inner class. Hence, there is no reference to the outer class Motherboard stored in Motherboard.this.

Key Points to Remember

  • Java treats the inner class as a regular member of a class. They are just like methods and variables declared inside a class.
  • Since inner classes are members of the outer class, you can apply any access modifiers like private, protected to your inner class which is not possible in normal classes.
  • Since the nested class is a member of its enclosing outer class, you can use the dot (.) notation to access the nested class and its members.
  • Using the nested class will make your code more readable and provide better encapsulation.
  • Las clases anidadas no estáticas (clases internas) tienen acceso a otros miembros de la clase externa / envolvente, incluso si se declaran privadas.

Articulos interesantes...