Bienvenidos sean a este post, hoy hablaremos sobre las clases internas las cuales son iguales a los metodos o las variables de una clase, estas pueden tener como miembro a otra clase, es decir que en Java se permite escribir una clase dentro de otra clase lo cual se llama clase anidada, y la clase que anida a estas clase se llama clase externa, veamos una sintaxis de como se utiliza:

class Clase_Externa {
class Clase_Interna {
}
}

Las clases anidadas se pueden dividir en dos tipos:

  • Clase anidada no estatica, son los miembros no estaticos de la clase
  • Clase anidada estatica, son los miembros estaticos de la clase

La clase anidada no estatica, es un tipo de mecanismo de seguridad de Java como hemos dicho en otra oportunidad las clases no pueden usar el modificador private por lo que si tenemos una clase miembro de otra clase, esta ultima la podemos hacer private y esto nos sirve para acceder a las partes privadas de una clase, las clases internas podemos dividirlas en tres tipos dependiendo en como y donde definirlas:

  • Clase Interna
  • Metodo-Local clase interna
  • Clase interna anonima

Hablemos sobre el primer tipo, clase interna, estas son realmente faciles de crear porque es simplemente crear una clase dentro de otra clase pero con la particularidad de que podemos declararla como privada y una vez declarada como esta no podra ser accedida desde un objeto por fuera de la clase, salvo como siempre por algun metodo publico de la clase para poner en practica veamos el siguiente ejemplo:

Mi_Clase.java

class Clase_Externa
{
        int num;

        private class Clase_Interna
        {
                public void imprimir()
                {
                        System.out.println(
                                "Esta es la clase interna");
                }
        }

        void mostrar_Interna()
        {
                Clase_Interna interno = new Clase_Interna();
                interno.imprimir();
        }
}

public class Mi_Clase
{
        public static void main(String[] args)
        {
                Clase_Externa externa = new Clase_Externa();
                externa.mostrar_Interna();
        }
}

En este caso vamos a tener una clase llamada Clase_Externa a la cual le agregamos una clase llamada Clase_Interna a la cual pudimos hacer private (privada) prohibiendo que cualquier pueda acceder por medio de un objeto fuera de la clase, y en esta clase vamos a tener un metodo llamado imprimir() el cual mostrara un mensaje en pantalla, volviendo a nuestra clase externa tendremos un metodo llamado mostrar_Interna() en la cual crearemos un objeto de nuestra clase interna y con ese objeto usamos el metodo imprimir() de la clase interna, esto es porque estamos dentro de la misma clase, saliendo de la clase externa pasemos a la clase principal en el cual tendremos el metodo main() en el cual crearemos un objeto de la clase Clase_Externa llamada externa y luego le diremos que utilice el metodo mostrar_Interna() para poder acceder al metodo imprimir() de la clase interna, compilemos y probemos nuestro programa:

tinchicus@dbn001vrt:~/programacion/java/program$ java Mi_Clase
Esta es la clase interna
tinchicus@dbn001vrt:~/programacion/java/program$

Como pueden ver pudimos acceder a nuestra clase interna por medio de un metodo de la clase externa, ahora vamos a suponer el caso contrario tenemos un miembro privado de la clase externa y accederemos a el por medio de una clase interna pero publica para verlo un poco mejor hagamos el siguiente ejemplo:

Mi_Clase2.java

class Clase_Externa
{
        private int num = 175;

        public class Clase_Interna
        {
                public int getNum()
                {
                        System.out.println(
                                "Este es el metodo de la clase interna");
                        return num;
                }
        }
}

public class Mi_Clase2
{
        public static void main(String[] args)
        {
                Clase_Externa externo = new Clase_Externa();

                Clase_Externa.Clase_Interna interno =
                                externo.new Clase_Interna();
                System.out.println(interno.getNum());
        }
}

En este caso tendremos a la variable llamada num como privada (private) a la cual no podremos acceder por medio del objeto creado de esta clase, para ello se creo la siguiente clase (Clase_Interna) la cual poseera un metodo llamado getNum() el cual mostrara un mensaje y luego le diremos que devuelva el valor de num, esto puede hacerlo por ser miembro de la clase externa, luego en el cuerpo de main() viene lo mas divertido, primero crearemos un objeto de la clase externa llamado externo, luego haremos otro objeto llamado interno pero sera de la clase externa (Clase_Externa) seguido de la clase interna (Clase_Interna) y despues el new vendra del objeto externo porque esta la forma de informarle donde esta ubicado el constructor de la clase interna, luego utilizando el metodo getNum() de la clase interna mostraremos el datos, compilemos el programa y ejecutemos el mismo:

tinchicus@dbn001vrt:~/programacion/java/program$ java Mi_Clase2
Este es el metodo de la clase interna
175
tinchicus@dbn001vrt:~/programacion/java/program$

En el ejemplo se puede ver que la forma de acceder a nuestras clases internas es similar a como accedemos al resto de nuestros miembros a traves de los objetos creados con esto terminado pasemos al siguiente tipo de clase interna: Metodo-Local.

Este tipo de clase interna es cuando creamos una clase dentro de un metodo de la clase externa, al igual que las variables esta clase tendra como limite el metodo y no pudiendo salir de esta, estas tienen la particularidad que unicamente pueden ser instanciadas dentro de la clase perteneciente a este tipo de clase interna, para entenderlo un poco mejor pasemos al siguiente ejemplo:

Claseexterna.java

public class Claseexterna
{
        void mi_metodo()
        {
                int num = 23;

                class Metodo_Interno
                {
                        public void imprimir()
                        {
                                System.out.println("Este es el metodo"
                                        + "interno de la clase: " + num);
                        }
                }

                Metodo_Interno interno = new Metodo_Interno();
                interno.imprimir();
        }

        public static void main(String[] args)
        {
                Claseexterna externo = new Claseexterna();
                externo.mi_metodo();
        }
}

En este caso volveremos a una clase, en la cual tendremos un metodo llamado mi_metodo(), en dicho metodo tendremos una variable llamada num, y una clase llamada metodo_Interno, la cual a su vez tendra un metodo llamado imprimir(), despues de esta clase pero todavia dentro de mi_metodo() crearemos un objeto de la clase dentro del metodo llamado interno con el cual llamaremos a imprimir(), cerramos el metodo mi_metodo() pasamos a main() donde crearemos un objeto llamado externo de la clase anterior y por medio de este objeto llamaremos a mi_metodo, si lo compilamos y ejecutamos obtendremos esta salida:

tinchicus@dbn001vrt:~/programacion/java/program$ java Claseexterna
Este es el metodointerno de la clase: 23
tinchicus@dbn001vrt:~/programacion/java/program$

Observen como nos ejecuto el metodo de la clase interna, esto es gracias a que en el metodo donde lo contiene creamos la instancia para poder acceder de lo contrario hubiera sido imposible porque este metodo solo existe en el metodo que contiene a la clase, esto es util para cuando necesitamos una mayor seguridad sobre el acceso a los metodos de una clase, aunque puede ser confuso.

Nuestra siguiente explicacion sera sobre la clase interna anonima, las mismas tienen la particularidad de ser declaradas sin un nombre de clase y se deben declarar e instanciar al mismo tiempo. Este tipo de clase se utiliza cuando se debe anular el metodo de una clase o una interfaz y su sintaxis es:

nombreClase nombreObjeto = new nombreClase(){
modificador nombreTipo nombreMetodo(){
…. Instrucciones ….
}
};

Como pueden ver la linea de declaracion de nuestra clase anonima es similar a cuando creamos un objeto de una clase pero con la diferencia de que abrimos una llave({}) luego declararemos y definiremos una funcion y por ultimo cerramos la llave y despues ponemos el punto y coma (;), esto es util cuando queremos redefinir un metodo similar pero con una accion distinta en sus instrucciones, para entenderlo un poco mejor veamos un ejemplo:

class AnonimaInterna
{
        public void mimetodo(){
                System.out.println("Hola");
        }
}

public class Clase_Externa
{
        public static void main(String[] args)
        {
                AnonimaInterna interna = new AnonimaInterna()
                {
                        public void mimetodo()
                        {
                                System.out.println("Este es un ejemplo"
                                        + " de clase anonima interna.");
                        }
                };
                interna.mimetodo();
        }
}

Este ejemplo es bien simple primero crearemos una clase llamada AnonimaInterna con un metodo declarado y definido llamado mimetodo(), el cual muestra un mensaje. Luego pasaremos a nuestro clase principal donde en el metodo main() veamos el siguiente bloque:

AnonimaInterna interna = new AnonimaInterna()
{
	public void mimetodo()
	{
		System.out.println("Este es un ejemplo"
			+ " de clase anonima interna.");
	}
};

Observen como la primera linea utiliza el mismo nombre de la clase que deseamos anular con el nombre de nuestro objeto abrimos la llave y declaramos un metodo del mismo nombre al que queremos anular, en este caso mimetodo() donde le diremos que muestre otro mensaje, observen como cerramos todo y despues lo finalizamos con un punto y coma (;) despues de este bloque llamamos al objeto que creamos con el metodo que definimos y observen como es la salida una vez compilado nuestro programa:

tinchicus@dbn001vrt:~/programacion/java/program$ java Clase_Externa
Este es un ejemplo de clase anonima interna.
tinchicus@dbn001vrt:~/programacion/java/program$

Por ultimo veamos un ejemplo donde utilizamos una clase interna anonima como argumento para un metodo:

Mi_Clase3.java

interface Mensaje
{
        String saludo();
}

public class Mi_Clase3
{
        public void mostrarMensaje(Mensaje m)
        {
                System.out.println(m.saludo() +
                        ", este es un ejemplo de una clase interna"
                        + " anonima como argumento");
        }

        public static void main(String args[])
        {
                Mi_Clase3 objeto = new Mi_Clase3();

                objeto.mostrarMensaje(new Mensaje() {
                        public String saludo() {
                                return "Holis";
                        }
                });
        }
}

Primero crearemos una simple interface la cual se llamara Mensaje y tendra un prototipo llamado saludo(), luego en el cuerpo de la clase declararemos un metodo llamdo mostrarMensaje() el cual tendra como argumento un elemento de la interfaz Mensaje, luego le diremos que a ese argumento llame al metodo saludo() y luego le agregaremos un texto, pasando al cuerpo del main, crearemos un objeto llamado objeto de la clase Mi_Clase3, veamos el siguiente bloque:

objeto.mostrarMensaje(new Mensaje() {
public String saludo() {
return "Holis";
}
});

Aca a nuestro objeto le instanciamos el metodo mostrarMensaje() y el argumento crearemos por medio del new un elemento de la interfaz donde abriremos una llave la cual contendra la definicion del prototipo de la interfaz, es decir saludo(), el cual retornara la frase “Holis”, y ese retorno sera enviado como argumento, si compilamos nuestro programa obtendremos la siguiente salida:

tinchicus@dbn001vrt:~/programacion/java/program$ java Mi_Clase3
Holis, este es un ejemplo de una clase interna anonima como argumento
tinchicus@dbn001vrt:~/programacion/java/program$

Observen como envio correctamente el texto de nuestro metodo utilizado como argumento y se mostro correctamente en el metodo mostrarMensaje() y para ir finalizando hablaremos sobre las clases internas estaticas.

Las clases internas estaticas, son aquellas que nos permiten acceder a las mismas sin necesidad de instanciar la clase externa pero no podremos acceder a las variables y metodos instanciados de la clase externa, su sintaxis es:

class ClaseExterna
{
static class ClaseAnidada
{
… Instrucciones …
}
}

Veamos el siguiente ejemplo:

Externa.java

public class Externa
{
        static class ClaseAnidada
        {
                public void mimetodo()
                {
                        System.out.println(
                                "Este es un ejemplo de clase anidada");
                }
        }

        public static void main(String[] args)
        {
                Externa.ClaseAnidada nido = new Externa.ClaseAnidada();
                nido.mimetodo();
        }
}

Vean como definimos a ClaseAnidada como estatica, esta tiene un metodo llamado mimetodo(), el cual muestra un mensaje, despues en el cuerpo de main() al crear el objeto nido primero ponemos la clase externa (Externa) luego como si fuera un metodo o variable miembro informamos la clase anidada lo mismo para llamar al constructor con la palabra new primero la clase externa y luego la anidada, por ultimo a este objeto le invocamos el metodo de la clase anidada, si compilamos y ejecutamos obtendremos esto:

tinchicus@dbn001vrt:~/programacion/java/program$ java Externa
Este es un ejemplo de clase anidada
tinchicus@dbn001vrt:~/programacion/java/program$

En resumen, hoy hemos visto las clases internas, que son, como pueden ser, cuantos tipos podemos encontrar, cuales son las diferencias entre cada tipo, ejemplos de cada una de ellas, las de tipo no estaticas y las estaticas, espero les haya sido util sigueme en Twitter o Facebook para recibir una notificacion cada vez que subo un nuevo post en este blog, nos vemos en el proximo post.

Anuncios