Ir al contenido principal

Clases internas en Java(Inner/nested classes)

Las clases internas en Java fueron introducidas desde la versión 1.1, desde entonces han sufrido grandes criticas, tanto positivas como negativas. Lo cierto es que son bastante útiles en ciertas ocasiones además de necesarias para entender el código de algunas aplicaciones interesantes.

Las clases internas proveen un mecanismo que nos permite definir una clase dentro de otra, así como una clase puede tener variables y métodos, también puede contener otras clases.

Una clase interna se crea cuando deseamos que haya una estrecha relación entre 2 clases que contienen métodos específicos pero que están sumamente relacionados unos con otros. Si se crea una clase interna, las variables y métodos de la clase dentro de la cual se encuentran estarán disponibles dentro de la clase interna, incluso aquellos marcados como privados(private).

Codificar un clase interna "Regular"::

Llamamos regular a aquella clase que no es:

1. Estática.
2. Método local.
3. Anónima.

Se define una clase interna dentro de las llaves de la clase externa, o sea, la clase que la contiene. P. ej.:

class MiClaseExterna{
class MiClaseInterna{ }
}

Al compilar dicha clase obtendremos 2 archivos de clase:

* MiClaseExterna.class
* MiClaseExterna$MiClaseInterna.class

Al final, la clase interna sigue siendo una clase separada de las demás, sin embargo, no se puede acceder a ella como lo hacemos usualmente en la línea de comandos de esta manera:

c:\> java MiClaseExterna$MiClaseInterna

Lo anterior no es posible debido a que una clase interna no tiene un método main ya que una clase interna regular no puede tener declaraciones estáticas de ningún tipo. La única manera de acceder a una clase interna es por medio de una instancia de la clase que la contiene (la clase externa). En otras palabras, solamente en tiempo de ejecución.

¿Cómo utilizamos una clase interna?. Simple, pasemos al código.

public class ClaseExterna {
private int x = 7;

//Definición de una clase interna
class MiClaseInterna{
public void verClaseExterna(){
System.out.println("El valor de X de la ClaseExterna es: "+ x);
}
}

public void crearInterna(){
//Crear una instancia de la clase interna
MiClaseInterna mci = new MiClaseInterna();
mci.verClaseExterna();
}

public static void main(String[] args)
{
ClaseExterna ce = new ClaseExterna();
ce.crearInterna(); //Llamamos al método que crea la clase interna
}

}

Analizando un poco lo que hemos hecho, nos damos cuenta de que accedemos a los métodos de la clase interna SOLAMENTE a través de una instancia de la clase que la contiene. La clase externa tiene un método (en este caso crearInterna()) que crea una instancia de la clase interna a partir de otra instancia de la clase externa y posteriormente en al misma función se manda a llamar el método verClaseExterna() que nos ayuda a imprimir el valor actual de la variable privada x. Pero ¿cómo instanciamos una clase interna fuera de la clase que la contiene?.

Crear un objeto de una clase interna fuera del código de instancia de la clase externa::

Supongamos que queremos utilizar un método de la clase interna fuera de la clase externa, es decir, en una clase independiente. Sabemos de antemano que para poder acceder a la clase interna necesitamos una instancia de la clase externa, entonces, tomando en cuenta que la siguiente clase es independiente de la ClaseExterna creada anteriormente pero que se encuentra en el mismo paquete y puede ser accedida sin problemas, la manera de acceder a dicho método sería la siguiente:

public class ClasesInternas {
public static void main (String[] args)
{
ClaseExterna ce = new ClaseExterna();
ClaseExterna.MiClaseInterna mci = ce.new MiClaseInterna();
mci.verClaseExterna();
}
}

o en una línea...

public static void main(String[] args)
{
ClaseExterna.MiClaseInterna mci = new ClaseExterna().new MiClaseInterna();
mci.verClaseExterna();
}


Es una sintaxis simple pero que debemos memorizarla si queremos utilizar clases internas en nuestras aplicaciones.


Referenciar una instancia de una clase interna o externa dentro de una clase interna::

De antemano sabemos (o debemos saber) que la manera en que un objeto hace referencia hacia él mismo es mediante la referencia this. Revisemos un poco la referencia this:

+ La palabra reservada this puede ser utilizada solamente dentro del código de instancia de una clase y no dentro de código estático.
+ Al referenciar con this, hacemos referencia(valga la redundancia) al objeto que se está ejecutando actualmente.
+ La referencia this es la manera en que un objeto puede pasarse a sí mismo como parámetro hacia un método. P. ej.:

public void miMetodo(){
MiClase mc = new MiClase();
mc.hacerAlgo(this); //se pasa como parámetro el objeto actual.
}

Dentro de una clase interna, la referencia a this apunta hacia la instancia e la clase interna, pero ¿cómo referenciamos a la clase externa desde la clase interna?, la respuesta en el siguiente código:

public class ClaseExterna {
private int x = 7;

//Definición de una clase interna
class MiClaseInterna{
public void verClaseExterna(){
System.out.println("El valor de X de la ClaseExterna es: "+ x);
System.out.println("La referencia a la clase interna: "+ this);
System.out.println("La referencia a la clase externa: "+ ClaseExterna.this);
}
}

public void crearInterna(){
//Crear una instancia de la clase interna
MiClaseInterna mci = new MiClaseInterna();
mci.verClaseExterna();
}

public static void main(String[] args)
{
ClaseExterna.MiClaseInterna mci = new ClaseExterna().new MiClaseInterna();
mci.verClaseExterna();
}
}


El resultado al ejecutar el código anterior es:

El valor de X de la ClaseExterna es: 7
La referencia a la clase interna: ClaseExterna$MiClaseInterna@112f614
La referencia a la clase externa: ClaseExterna@1d9dc39

Así que:
+ Para referenciar una clase interna dentro de la clase interna se utiliza this.
+ Para referenciar una clase externa dentro de la clase interna se utiliza NombreDeLaClaseExterna.this

Debido a que una clase interna es un miembro actual de la clase externa, se pueden aplicar controles de acceso tal como lo hacemos con variables y métodos. Los modificadores aplicables a clases internas son:

+ final
+ abstract
+ public
+ private
+ protected
+ static (lo que la volvería una clase anidada estática, no una clase interna)
+ strictfp

Hasta aquí la primera parte de clases internas en Java. ¿Alguna duda? deja tu comentario.

Más sobre programación en Java aquí.

Comentarios

  1. Muy buena explicacion de veras, etsoi aprendiendo java en un gardo superiro de DAI y te asseguro que lo he entendido mejor que con la professora de veras eres muy grande.
    Gracias David

    ResponderBorrar
  2. de 10, me sirvio
    servicio tecnico Gonzalo, Villa Nueva, Córdoba, Arg

    ResponderBorrar
  3. tu explicacion es muy buena pero te agradeceria si colocaras ejemplos practicos, quiero decir, en que momento se recomienda utilizar clases internas o como se que tengo que utilizar clases internas. gracias de antemano

    ResponderBorrar
  4. excelente aporte... muy bien explicado (espero la segunda parte, jeje

    ResponderBorrar
  5. Solo queria agradecerte por tan maravillosa explicación coherente y de mucho utilidad.
    Mil y mil gracias felicidades por el trabajo realizado.

    ResponderBorrar
  6. Muuy buena explicación, me habia costado mucho entender claramente este concepto de clases internas.

    ResponderBorrar
  7. Muy buena y clara la explicación ... gracias.

    ResponderBorrar
  8. Excelente explicacion amigo.
    Agradesco tu aporte.
    Saludos desde Lima - Peru

    ResponderBorrar
  9. Hola, he descubierto una cosa interesante,si creas un objeto de una clase interna No estática, sólo lo puedes hacer a través de una referencia a un objeto de la clase contenedora, ejemplo: A.B b1 = a1.new B();
    Pero si la clase interna es estática sólo me permite crear un objeto a través de una referencia a la clase_contenedora.clase_interna();
    A.Bs b1 = new A.Bs();
    Por cierto, muy bueno el blog.

    ResponderBorrar
  10. muchisimas gracias me salvaste

    ResponderBorrar
  11. Este comentario ha sido eliminado por el autor.

    ResponderBorrar
  12. Muy buena explicación de las clases internas, muchas gracias

    ResponderBorrar
  13. Muy buena explicación, pero que ocurre si la clase externa y es abstract?

    ResponderBorrar

Publicar un comentario

Este es un espacio abierto, puedes escribir lo que gustes respetando los siguientes puntos:

1.- Lo que escribas esté relacionado con el post, si gustas contactarme puedes hacerlo aqui.

2.- Todo es cuestionable, aunque ten en cuenta que existen formas de hacerlo, evita las agresiones y revisa tu lenguaje antes de publicar un comentario.

3.- Siempre hay tres verdades: tu verdad, mi verdad y la verdad, por lo que opiniones diferentes no necesariamente son equivocadas.

4.- Los comentarios son una forma de discusión abierta, por lo que al publicar uno, implícitamente entras a una discusión, con todo lo que esto representa.

5. Me reservo el derecho de eliminar comentarios que no respeten las condiciones mencionadas anteriormente.

Toma en cuenta que puedes utilizar emoticones en tu comentario, para ver una lista de los disponibles da clic en este enlace.

Entradas más populares de este blog

3 sencillos pasos para tramitar la ayuda por desempleo de la AFORE

¿Tienes dinero ahorrado en tu AFORE y en este momento no estás trabajando o estás trabajando pero no tienes seguro social? Si respondiste sí a la pregunta anterior entonces hay una buena noticia para ti: puedes retirar una parte del dinero que tienes ahorrado. Y lo mejor, es muy sencillo. En este artículo te diré paso a paso qué hacer para obtener ese dinero, sin tecnicismos legales ni nada por el estilo, simple y sencillamente lo que necesitas saber. Paso Número 1: Obtener los últimos 2 estados de cuenta de tu Afore Esto en la mayoría de los casos es sumamente sencillo ya que dichos estados de cuenta llegan directamente al domicilio del ahorrador, si este es tu caso puedes saltar lo restante en este punto y continuar con el paso número 2, en caso contrario sigue leyendo… Si no tienes tus estados de cuenta debes ponerte en contacto con la empresa encargada de administrar tu ahorro para que te los proporcione, normalmente te van a pedir una identificación oficial, comprobante de

Conectar una base de datos en MySQL con NetBeans

NetBeans es una plataforma para el desarrollo de aplicaciones de escritorio usando Java y a un Entorno integrado de desarrollo (IDE) desarrollado usando la Plataforma NetBeans. Si eres un programador y desarrollas tus aplicaciones en Java seguramente necesitarás conectar una base de datos tipo MySQL a este entorno algún día, bueno, si lo necesitas ahora, he aquí una explicación paso a paso de cómo conectar ambas herramientas.

4 extraordinarias aplicaciones espía para Android

Le andas haciendo al James Bond y necesitas grabar video, voz o tomar fotos desde tu dispositivo Android sin ser notado? Aquí 4 excelentes aplicaciones que facilitarán tus hazañas de 007 en menos de lo que canta un gallo.

c606 c6nf5g4r6 e3 tec3ad6 [Como configurar el teclado]

¿Problemas al escribir con el teclado? ¿Tratas de escribir la letra ‘o’ y sale el número ‘6’ o algo por el estilo? La solución puede ser más simple de lo que parece. La solución a tu problema tras el salto...

Conexión, consulta y ejecución de sentencias en MySQL con Java

Anteriormente escribí este mismo artículo pero para bases de datos en Oracle . En este artículo prácticamente me copio y pego para explicar paso a paso cómo realizar la conexión a MySQL en Java, así como la forma de realizar consultas a los registros existentes y ejecutar sentencias de inserción, borrado y actualización de datos. Al final del artículo tendremos una clase que encapsulará todos los procedimientos necesarios para trabajar con la base de datos.