En programación orientada a objetos (POO), una clase interna o clase anidada es una clase declarada completamente dentro del cuerpo de otra clase o interfaz. Se distingue de una subclase .
Una instancia de una clase normal o de nivel superior puede existir por sí sola. Por el contrario, una instancia de una clase interna no puede instanciarse sin estar vinculada a una clase de nivel superior.
Tomemos la noción abstracta de un Car
con cuatro Wheel
s. Nuestros Wheel
s tienen una característica específica que depende de ser parte de nuestro Car
. Esta noción no representa a los Wheel
s como Wheel
s en una forma más general que podría ser parte de cualquier vehículo. En cambio, los representa como específicos de un Car
. Podemos modelar esta noción utilizando clases internas de la siguiente manera:
Tenemos la clase de nivel superior Car
. Las instancias de la clase Car
se componen de cuatro instancias de la clase Wheel
. Esta implementación particular de Wheel
es específica de un automóvil, por lo que el código no modela la noción general de una rueda que se representaría mejor como una clase de nivel superior. Por lo tanto, está semánticamente conectada a la clase Car
y el código de Wheel
está de alguna manera acoplado a su clase externa, siendo una unidad de composición de un automóvil. La rueda de un automóvil en particular es exclusiva de ese automóvil, pero para la generalización, la rueda es una unidad de agregación del automóvil.
Las clases internas proporcionan un mecanismo para modelar con precisión esta conexión. Podemos referirnos a nuestra Wheel
clase como Car.Wheel
, Car
siendo la clase de nivel superior y Wheel
siendo la clase interna.
Por lo tanto, las clases internas permiten la orientación a objetos de ciertas partes del programa que de otro modo no quedarían encapsuladas en una clase.
Los segmentos de código más grandes dentro de una clase podrían modelarse o refactorizarse mejor como una clase de nivel superior separada, en lugar de una clase interna. Esto haría que el código fuera más general en su aplicación y, por lo tanto, más reutilizable, pero potencialmente podría ser una generalización prematura. Esto puede resultar más efectivo si el código tiene muchas clases internas con la funcionalidad compartida.
En Java hay cuatro tipos de clases anidadas :
static
. Al igual que otras cosas en el ámbito estático (es decir, métodos estáticos ), no tienen una instancia envolvente y no pueden acceder a las variables de instancia y los métodos de la clase envolvente. Son casi idénticas a las clases no anidadas excepto por los detalles del ámbito (pueden hacer referencia a variables y métodos estáticos de la clase envolvente sin calificar el nombre; otras clases que no son una de sus clases envolventes tienen que calificar su nombre con el nombre de su clase envolvente). Las interfaces anidadas son implícitamente estáticas.Clase interna: las siguientes categorías se denominan clases internas . Cada instancia de estas clases tiene una referencia a una instancia envolvente (es decir, una instancia de la clase envolvente), excepto las clases locales y anónimas declaradas en un contexto estático. Por lo tanto, pueden hacer referencia implícita a variables de instancia y métodos de la clase envolvente. La referencia de instancia envolvente se puede obtener explícitamente mediante EnclosingClassName.this
. Las clases internas no pueden tener variables o métodos estáticos, excepto las variables constantes de tiempo de compilación. Cuando se crean, deben tener una referencia a una instancia de la clase envolvente; lo que significa que deben crearse dentro de un método de instancia o constructor de la clase envolvente, o (para clases miembro y anónimas) crearse utilizando la sintaxis enclosingInstance.new InnerClass()
. [1]
Las clases internas locales se utilizan a menudo en Java para definir devoluciones de llamadas para el código de la interfaz gráfica de usuario. Los componentes pueden compartir un objeto que implementa una interfaz de manejo de eventos o extiende una clase adaptadora abstracta, que contiene el código que se ejecutará cuando se active un evento determinado.
También se utilizan clases internas anónimas cuando el código de manejo de eventos solo lo utiliza un componente y, por lo tanto, no necesita una referencia con nombre.
Esto evita un método monolítico grande actionPerformed(ActionEvent)
con múltiples ramas if-else para identificar la fuente del evento. Este tipo de código se considera a menudo desordenado [ cita requerida ] y las variaciones de clase interna se consideran mejores en todos los aspectos. [ cita requerida ]