Clase interior - Inner class

En la programación orientada a objetos (OOP), una clase interna o clase anidada es una clase declarada completamente dentro del cuerpo de otra clase o interfaz. Se distingue de una subclase .

Visión de conjunto

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 se puede instanciar sin estar vinculada a una clase de nivel superior.

Tomemos la noción abstracta de a Carcon cuatro Wheels. Nuestros Wheels tienen una característica específica que se basa en ser parte de nuestro Car. Esta noción no representa el Wheels como Wheels en una forma más general que podría ser parte de cualquier vehículo. En cambio, los representa como específicos de a Car. Podemos modelar esta noción usando clases internas de la siguiente manera:

Tenemos la clase de primer nivel Car. Las instancias de clase Carse componen de cuatro instancias de la clase Wheel. Esta implementación particular de Wheeles específica de un automóvil, por lo que el código no modela la noción general de una rueda que estaría mejor representada como una clase de nivel superior. Por lo tanto, está semánticamente conectado a la clase Cary el código de Wheelestá acoplado de alguna manera 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 generalizar, la rueda es una unidad de agregación para el automóvil.

Las clases internas proporcionan un mecanismo para modelar con precisión esta conexión. Podemos referirnos a nuestra Wheelclase como Car.Wheel, Carser la clase de nivel superior y Wheelser 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 se encapsularían en una clase.

Es posible que los segmentos más grandes de código dentro de una clase se modelen o refactoricen 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 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.

Tipos de clases anidadas en Java

En Java hay cuatro tipos de clases anidadas :

Estático
  • Clase miembro estática, también llamada clases anidadas estáticas  : se declaran static. Como otras cosas en el alcance estático (es decir, métodos estáticos ), no tienen una instancia adjunta y no pueden acceder a las variables de instancia y métodos de la clase adjunta. Son casi idénticas a las clases no anidadas excepto por los detalles del alcance (pueden referirse a variables estáticas y métodos de la clase adjunta sin calificar el nombre; otras clases que no son una de sus clases adjuntas tienen que calificar su nombre con la clase adjunta nombre). Las interfaces anidadas son implícitamente estáticas.
Clases internas / no estáticas

Clase interna: las siguientes categorías se denominan clases internas . Cada instancia de estas clases tiene una referencia a una instancia adjunta (es decir, una instancia de la clase adjunta), excepto para las clases locales y anónimas declaradas en contexto estático. Por tanto, pueden referirse implícitamente a variables de instancia y métodos de la clase adjunta. La referencia de instancia adjunta se puede obtener explícitamente a través de EnclosingClassName.this. Las clases internas pueden no tener variables o métodos estáticos, excepto para las variables constantes en tiempo de compilación. Cuando se crean, deben tener una referencia a una instancia de la clase adjunta; lo que significa que deben crearse dentro de un método de instancia o constructor de la clase adjunta, o (para clases miembro y anónimas) deben crearse utilizando la sintaxis enclosingInstance.new InnerClass().

  • Clase de miembro: se declaran fuera de una función (por lo tanto, un "miembro") y no se declaran "estáticos".
  • Clase local: son clases que se declaran en el cuerpo de una función. Solo se puede hacer referencia a ellos en el resto de la función. Pueden usar variables locales y parámetros de la función, pero solo uno que se declare "final". (Esto se debe a que la instancia de la clase local debe mantener una copia separada de la variable, ya que puede sobrevivir a la función; para no tener la confusión de dos variables modificables con el mismo nombre en el mismo ámbito, la variable se fuerza no modificable.) Puede ser muy útil para crear una clase con campos de tipo genérico, donde las variables de tipo se definen en el método.
  • Clase anónima  : son clases locales que se declaran e instancian automáticamente en medio de una expresión. Solo pueden extender directamente una clase o implementar una interfaz. Pueden especificar argumentos para el constructor de la superclase, pero no pueden tener un constructor de otra manera (sin embargo, esto no es una limitación, ya que puede tener un bloque inicializador de instancia para realizar cualquier inicialización).

Lenguajes de programación

  • Las clases internas se convirtieron en una característica del lenguaje de programación Java a partir de la versión 1.1.
  • Las clases anidadas también son una característica del lenguaje de programación D , Visual Basic .NET , Ruby , C ++ y C # .
  • En Python , es posible anidar una clase dentro de otra clase, método o función.
  • C ++ tiene clases anidadas que son como las clases de miembros estáticos de Java, excepto que no se declaran con "estática".
  • El lenguaje BETA introdujo esta noción de clases anidadas.

Código GUI

Las clases internas locales se utilizan a menudo en Java para definir devoluciones de llamada para el código GUI. Los componentes pueden compartir un objeto que implementa una interfaz de manejo de eventos o extiende una clase de adaptador abstracto, que contiene el código que se ejecutará cuando se active un evento determinado.

Las clases internas anónimas también se usan cuando el código de manejo de eventos solo lo usa un componente y, por lo tanto, no necesita una referencia con nombre.

Esto evita un actionPerformed(ActionEvent)método monolítico grande con múltiples ramas if-else para identificar la fuente del evento. Este tipo de código a menudo se considera desordenado y las variaciones de clases internas se consideran mejores en todos los aspectos.

Referencias

enlaces externos