Clase interna y anidada de Java
Clase interna y anidada de Java
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. Dicha 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 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 envolvente (clase externa). Es comúnmente conocido como inner class
.
Desde el inner class
existe dentro de la clase externa, primero debe instanciar la clase externa para poder instanciar la clase interna.
Aquí hay un ejemplo de cómo puede declarar clases internas en Java.
Ejemplo 1:Clase interna
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 :
Processor Cache = 4.3 Ram Clock speed = 5.5
En el programa anterior, hay dos clases anidadas:Processor y RAM dentro de la clase exterior:CPU . Podemos declarar la clase interna como protegida. Por lo tanto, hemos declarado la clase RAM como protegida.
Dentro de la clase Principal,
- primero creamos una instancia de una clase externa CPU llamado 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 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 información sobre esta palabra clave, visite Java esta palabra clave.
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 :
Engine Type for 8WD= Bigger Engine Type for 4WD = Smaller
En el programa anterior, tenemos la clase interna llamada Engine dentro de la clase exterior Coche . Aquí, observe la línea,
if(Car.this.carType.equals("4WD")) {...}
Estamos usando this
palabra clave para acceder al carType variable de la clase exterior. Es posible que haya notado que en lugar de usar this.carType
hemos usado Car.this.carType
.
Es porque si no hubiéramos mencionado el nombre de la clase externa Coche , luego this
palabra 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 tener en cuenta que, aunque el getCarName()
es un private
método, podemos acceder a él desde la clase interna.
Clase anidada estática
En Java, también podemos definir un static
clase dentro de otra clase. Dicha 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 Ports = 3
En el programa anterior, hemos creado una clase estática llamada USB dentro de la clase MotherBoard . Fíjate en 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é sucedería si intentas acceder a los miembros de la clase externa:
Ejemplo 4:Acceso a miembros de la clase Exterior dentro de la Clase Interior 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: non-static variable this cannot be referenced from a static context
Esto se debe a que no estamos usando el objeto de la clase externa para crear un objeto de la clase interna. Por lo tanto, no hay referencia a la clase externa Motherboard
almacenado en Motherboard.this
.
Puntos clave para recordar
- Java trata la clase interna como un miembro regular de una clase. Son como métodos y variables declaradas dentro de una clase.
- Dado que las clases internas son miembros de la clase externa, puede aplicar cualquier modificador de acceso como
private
,protected
a su clase interna que no es posible en las clases normales. - Dado que la clase anidada es un miembro de su clase externa envolvente, puede usar el punto (
.
) notación para acceder a la clase anidada y sus miembros. - Usar la clase anidada hará que su código sea más legible y proporcionará una mejor encapsulación.
- Las clases anidadas no estáticas (clases internas) tienen acceso a otros miembros de la clase externa/incluyente, incluso si se declaran privadas.
Java