Las clases internas en Java son clases definidas dentro de otra clase. Estas clases pueden acceder a los miembros de la clase externa, incluso si son privados. Las clases internas se utilizan principalmente para agrupar clases que solo se utilizan en un lugar, aumentando la encapsulación y la legibilidad del código.
Tipos de Clases Internas
Java soporta varios tipos de clases internas:
- Clases Internas No Estáticas (Inner Classes)
- Clases Internas Estáticas (Static Nested Classes)
- Clases Locales (Local Classes)
- Clases Anónimas (Anonymous Classes)
- Clases Internas No Estáticas (Inner Classes)
Las clases internas no estáticas son clases definidas dentro de otra clase sin el modificador static
. Estas clases tienen acceso a todos los miembros de la clase externa, incluyendo los privados.
Ejemplo:
public class OuterClass { private String outerField = "Outer Field"; class InnerClass { void display() { System.out.println("Accessing: " + outerField); } } public static void main(String[] args) { OuterClass outer = new OuterClass(); OuterClass.InnerClass inner = outer.new InnerClass(); inner.display(); } }
Explicación:
OuterClass
es la clase externa.InnerClass
es la clase interna no estática.InnerClass
puede acceder al campoouterField
deOuterClass
.
- Clases Internas Estáticas (Static Nested Classes)
Las clases internas estáticas se definen con el modificador static
. Estas clases no pueden acceder directamente a los miembros de la clase externa, a menos que sean estáticos.
Ejemplo:
public class OuterClass { private static String staticOuterField = "Static Outer Field"; static class StaticNestedClass { void display() { System.out.println("Accessing: " + staticOuterField); } } public static void main(String[] args) { OuterClass.StaticNestedClass nested = new OuterClass.StaticNestedClass(); nested.display(); } }
Explicación:
StaticNestedClass
es una clase interna estática.- Puede acceder al campo
staticOuterField
deOuterClass
porque es estático.
- Clases Locales (Local Classes)
Las clases locales son clases definidas dentro de un método. Estas clases solo son accesibles dentro del método donde se definen.
Ejemplo:
public class OuterClass { void outerMethod() { class LocalClass { void display() { System.out.println("Inside Local Class"); } } LocalClass local = new LocalClass(); local.display(); } public static void main(String[] args) { OuterClass outer = new OuterClass(); outer.outerMethod(); } }
Explicación:
LocalClass
es una clase local definida dentro del métodoouterMethod
.- Solo es accesible dentro de
outerMethod
.
- Clases Anónimas (Anonymous Classes)
Las clases anónimas son clases sin nombre que se declaran e instancian en una sola expresión. Se utilizan principalmente para implementar interfaces o clases abstractas.
Ejemplo:
public class OuterClass { interface Greeting { void greet(); } void displayGreeting() { Greeting greeting = new Greeting() { public void greet() { System.out.println("Hello from Anonymous Class"); } }; greeting.greet(); } public static void main(String[] args) { OuterClass outer = new OuterClass(); outer.displayGreeting(); } }
Explicación:
Greeting
es una interfaz.- Se crea una clase anónima que implementa
Greeting
y se instancia en la misma expresión.
Ejercicios Prácticos
Ejercicio 1: Clase Interna No Estática
Instrucciones:
- Crea una clase
Library
con un camponame
. - Dentro de
Library
, crea una clase internaBook
con un campotitle
. - En
Book
, crea un métododisplayDetails
que imprima el nombre de la biblioteca y el título del libro. - En el método
main
, crea una instancia deLibrary
y una instancia deBook
, y llama adisplayDetails
.
Solución:
public class Library { private String name; Library(String name) { this.name = name; } class Book { private String title; Book(String title) { this.title = title; } void displayDetails() { System.out.println("Library: " + name + ", Book: " + title); } } public static void main(String[] args) { Library library = new Library("City Library"); Library.Book book = library.new Book("Java Programming"); book.displayDetails(); } }
Ejercicio 2: Clase Interna Estática
Instrucciones:
- Crea una clase
University
con un campo estáticouniversityName
. - Dentro de
University
, crea una clase interna estáticaDepartment
con un campodepartmentName
. - En
Department
, crea un métododisplayDetails
que imprima el nombre de la universidad y el nombre del departamento. - En el método
main
, crea una instancia deDepartment
y llama adisplayDetails
.
Solución:
public class University { private static String universityName = "Global University"; static class Department { private String departmentName; Department(String departmentName) { this.departmentName = departmentName; } void displayDetails() { System.out.println("University: " + universityName + ", Department: " + departmentName); } } public static void main(String[] args) { University.Department department = new University.Department("Computer Science"); department.displayDetails(); } }
Conclusión
Las clases internas en Java son una poderosa herramienta para mejorar la encapsulación y la organización del código. Al entender y utilizar los diferentes tipos de clases internas, puedes escribir código más limpio y modular. En el siguiente tema, exploraremos las clases anónimas con más detalle, que son una forma especial de clases internas utilizadas para simplificar la implementación de interfaces y clases abstractas.
Curso de Programación en Java
Módulo 1: Introducción a Java
- Introducción a Java
- Configuración del Entorno de Desarrollo
- Sintaxis y Estructura Básica
- Variables y Tipos de Datos
- Operadores
Módulo 2: Flujo de Control
Módulo 3: Programación Orientada a Objetos
- Introducción a la POO
- Clases y Objetos
- Métodos
- Constructores
- Herencia
- Polimorfismo
- Encapsulamiento
- Abstracción
Módulo 4: Programación Orientada a Objetos Avanzada
Módulo 5: Estructuras de Datos y Colecciones
Módulo 6: Manejo de Excepciones
- Introducción a las Excepciones
- Bloque Try-Catch
- Throw y Throws
- Excepciones Personalizadas
- Bloque Finally
Módulo 7: Entrada/Salida de Archivos
- Lectura de Archivos
- Escritura de Archivos
- Flujos de Archivos
- BufferedReader y BufferedWriter
- Serialización
Módulo 8: Multihilo y Concurrencia
- Introducción al Multihilo
- Creación de Hilos
- Ciclo de Vida de un Hilo
- Sincronización
- Utilidades de Concurrencia
Módulo 9: Redes
- Introducción a las Redes
- Sockets
- ServerSocket
- DatagramSocket y DatagramPacket
- URL y HttpURLConnection