Inicio > Java > Java Clases Internas Anónimas

Java Clases Internas Anónimas

Muchas veces mas de alguna vez se preguntaron al agregarle un evento a un boton lo siguiente:
Por que al instanciar un ActionListener hay que poner unas llaves

ActionListener action = new ActionListener() {
	//...
};

La respuesta a esa interrogante es la siguiente:
ActionListener no es una class, sino que es una interface , eso quiere decir que no esta completa y alguna clase tiene que implementarla.
La forma común que conocemos de implementar es la siguiente:

interface IOrden {
	Object mayor(Object o);
}
/* Con la palabra reservada 'implements' tomo un acuerdo de implementar la interface */
public class Persona implements IOrden {
	//...
	/* Aqui implemento la interface */
	public Object mayor(Object o) {
		//...
	}
}

El codigo anterior muestra como la clase Persona implementó IOrden .

Otra forma de implementar interface es creando clases anónimas…
¿ que quiere decir esto ?
una clase sin nombre y sin una visibilidad definida.
Un ejemplo de clase anónima es la que ocupamos cuando agregamos ActionListener, al ser una interface debe ser implementada por alguna clase, nosotros a menudo la implementamos con una clase anónima
Ej:

ActionListener action = new ActionListener() {
	//...
};

Lo que esta entre llaves es la clase anónima que esta dentro de otra clase.

Ej:

import javax.swing.*;
import java.awt.event.*;
import java.awt.*;
 
public class Tips {
    public int numero = 1;
    public Tips() {
    	/* Creo un Objeto de la Clase JFrame */
		JFrame win = new JFrame();
		/* A esa ventana le doy un ancho y alto */
		win.setSize(300,200);
		
		/* Creo un Objeto de la clase JButton */
		JButton b = new JButton("Clickear");
		/* A ese boton le agrego un evento */
		ActionListener click = new ActionListener() {
			public int numero=2;
			public void actionPerformed(ActionEvent e) {
				JOptionPane.showMessageDialog(null,"Hola "+this.numero);
			}
		};
		b.addActionListener(click);
		
		/* Agrego el Boton al contenedor de la ventana */
		win.getContentPane().add(b);
		/* Muestro la ventana */
		win.setVisible(true);
    }
    
    public static void main(String[] args) {
    	new Tips();
    }
}

Para explicar lo anterior fijemonos en la siguientes lineas:

ActionListener click = new ActionListener() {
			public int numero=2;
			public void actionPerformed(ActionEvent e) {
				JOptionPane.showMessageDialog(null,"Hola "+this.numero);
			}
		};

El objeto click es de una instancia de ActionListener , esta a su vez implementa la interface con una clase anónima, pero a su vez esa clase anónima esta dentro de la clase Tips.

Algo interesante es lo que pasa cuando ejecuto la siguiente linea:

JOptionPane.showMessageDialog(null,"Hola "+this.numero);

Esa linea debería mostrarnos una alerta por pantalla… Pero fijense:
La clase Tips tiene un atributo llamado:

public int numero = 1;

y la clase anónima tambien tiene un atributo:

public int numero=2;

Entonces ¿ A que atributo debía llamar la alerta ?

la palabra reservada this es para referenciar a elementos (atributos o metodos) de esta clase

JOptionPane.showMessageDialog(null,"Hola "+this.numero);

Como esa linea esta dentro del método actionPerformed y ese metodo está dentro de la clase anónima. El this ,en éste caso, va a hacer referencia al atributo dentro de dicha clase anonima, por lo que debería mostrar

Hola 2

Por eso nunca dentro del

public void actionPerformed(ActionEvent e) {
//...
}

Nunca deben llamar a elementos (métodos o atributos) con this, osino tendrán un error que el metodo o atributo no fue encontrado porque buscara el atributo en la clase anónima y no en la que anida dicha clase anónima.

Espero que les quede un poco mas claro,

Saludos!

Categorías:Java Etiquetas: , , , ,
  1. Manuel Castro
    diciembre 27, 2009 a las 7:48 pm

    Buena explicación… pero cómo entonces podemos referenciar a la clase superior ya que no podemos utilizar this?

    • estebanfuentealba
      diciembre 27, 2009 a las 11:08 pm

      Una opcion es declarar un atributo del tipo del mismo tipo de clase , asignar el this a ese atributo en el constructor y ocupar el atributo dentro del listener

      Ejemplo:

      public class Superior {
      	private Superior miThis;
      	private int numero=0;
      	//...
      	public Superior() {
      		this.miThis = this;
      		//...
      		this.programaEventos();
      	}
      	public void programaEventos() {
      		ActionListener click = new ActionListener() {
      			public void actionPerformed(ActionEvent e) {
      				System.out.println(miThis.getNumero());
      			}
      		};
      		b.addActionListener(click);
      	}
      	public int getNumero() {
      		return this.numero;
      	}
      }
      
  2. febrero 11, 2010 a las 1:25 pm

    Gracias por el artículo, era justo lo que estaba buscando.
    Saludos

    • Eduardo
      febrero 28, 2010 a las 12:38 am

      Buena explicación… pero cómo entonces podemos referenciar a la clase superior ya que no podemos utilizar this?

      otro escape no seria usar
      ClaseSuperio.this;
      asi como en las clases-method-local-inner ?
      aqui lo acabo de hacer :D *_*

      public class Main {
      public int algo;
      /* No se esta creando un objeto interface ya que es algo herrado
      * lo q se esta haciendo es crear un objeto anonimo q esta
      * implementado la interface Interface. Y este objeto anónimo al
      * implementar Interface puede ser seteado en la variable inter
      * (Se está aplicando polimorfismo).
      */

      Interface inter = new Interface() {

      public int suma(int a, int b) {
      return a + b;
      }

      public int getResultado() {
      System.out.println("Resultado d 6+6");
      return inter.suma(6, 6);
      }

      public void doSth() {
      System.out.println(Main.this.algo);
      }

      };

  3. Eduardo
    febrero 28, 2010 a las 12:41 am

    Muy buengo gracias ^^. Aunque apenas voy x el scjp xD
    un saludo !
    happy coding \(^,^)/

  4. abril 12, 2012 a las 12:07 am

    Excelente explicación un 10 de 10 justo lo que estaba buscando

  5. abril 12, 2012 a las 12:09 am

    Excelente era justo lo que estaba buscando, porque cuando vi en un articulo eso de clases anónimas me dejo con ganas de ver que era eso y me ayudo tu material gracias :)

  1. No trackbacks yet.

Responder

Introduce tus datos o haz clic en un icono para iniciar sesión:

Logo de WordPress.com

Estás comentando usando tu cuenta de WordPress.com. Cerrar sesión / Cambiar )

Imagen de Twitter

Estás comentando usando tu cuenta de Twitter. Cerrar sesión / Cambiar )

Foto de Facebook

Estás comentando usando tu cuenta de Facebook. Cerrar sesión / Cambiar )

Google+ photo

Estás comentando usando tu cuenta de Google+. Cerrar sesión / Cambiar )

Conectando a %s

A %d blogueros les gusta esto: