Java - Clase Anónima
Concepto
-
Clasesin nombre que define y utiliza en un solo lugar en el código -
Permite
declarareinstanciarunaclaseal mismo tiempo invocando unainterfaceoclase extensiblecomo unaclase abstracta -
Son como
clases localesexcepto queno tienen nombre
Se utiliza para crear y usar una
clase localuna sola vez
Ventajas
-
Son
clasesse usan sobre todo comoescuchadores-Listeners,CallbacksoEventos -
Pueden acceder a
variables localesque se encuentren a su entorno
Declaración
-
Las
clases localesson declaraciones de clase- las
clases anónimassonexpresiones→ define laclaseenotra expresión
- las
Sintaxis
Recuerda :
Clase anónima→expresión
-
Sintaxisde unaexpresióndeclase anónima- Es como la invocación de un
constructorexcepto que hay unadefinicióndeclase contenidaen unbloque de código
- Es como la invocación de un
-
Considere la
instanciacióndel objetofrenchGreeting
// Clase Anónima
// ↓
HelloWorld frenchGreeting = new HelloWorld() {
String name = "tout le monde";
// Método heredados de la interface HelloWorld e implementados in situs
public void greet() {
greetSomeone("tout le monde");
}
// Método heredados de la interface HelloWorld e implementados in situs
public void greetSomeone(String someone) {
name = someone;
System.out.println("Salut " + name);
}
};
-
La
expresióndeclase anónimaconsta-
El
nuevo operador -
El nombre de una
interfazpara implementar o unaclaseparaextender
-
-
Ejemplo
- La
clase anónimaimplementa lainterfaz HelloWorld
- La
-
Paréntesisque contienen losargumentosde unconstructor, como unaexpresióndecreacióndeinstanciadeclase concretaCuando implementa una interfaz no hay un constructor por lo que usa un par de paréntesis vacíos, como en este ejemplo
-
El
cuerpoque es una dedeclaración de clase- Se permiten las
declaraciones de métodosperonolasdeclaraciones
- Se permiten las
-
Definicióndeclase anónimaes unaexpresiónque debe ser parte de unadeclaración-
Ejemplo
-
La expresión de
clase anónimaes parte de lainstrucciónqueinstanciaelobjeto frenchGreetingEsto explica por qué hay un punto y coma después de la llave de cierre
-
-
Acceso Variables Locales (Ámbito de la Aplicación)
-
Puede capturar
variables locales- Tienen el
mismo ámbitode acceso a lasvariables locales
- Tienen el
-
Clase anónima-
Tiene
accesoa losmiembrosde suclase envolvente -
No puede acceder a las
variables localesen su ámbito adjunto que no estén declaradas como finales -
Igual que las
clases anidadasladeclaraciónde untipo( como una variable ) en unaclase anónimaoculta cualquier otra declaración en elámbitode la aplicación que tenga el mismo nombre
-
Permite
-
Campos →
Fields -
Métodos adicionales( incluso si no implementan ningúnmétodode laSuperClase) -
Inicializadores de instancia →
Constructores -
Clases locales
Restricciones
-
No puede declarar
elementos estáticos -
No puede declarar nuevos
atributos miembrosde lasinterfaces -
Permite
atributos miembros estáticossiempre que sean deltipo constantes
Ejemplos
1. Ejemplo
-
Tenemos interfaz llamada
Operacionque tiene unmétodollamadorealizarOperaciontomados enterosydevuelvesu suma -
Podemos
implementarestainterfaz
// Clase Anónima
// ↓
Operacion suma = new Operacion() { // Expresión completa de la Clase Anónima
// Método heredado e implementado
public int realizarOperacion(int a, int b) {
return a + b;
}
}; // Fin de la implementación de la Clase Anónima
-
Explicación
-
Estamos creando una
clase anónimaque implementa la interfaz “Operacion” y redefine elmétodo realizarOperacion()para que devuelva la suma de dos números -
La
clase anónimase crea en elmismo lugar donde se utilizayno tiene un nombre propio -
Ejemplo en el que se puede usar una
clase anónimaes cuandose necesitaheredar de unaclase existenteyredefiniralgunos de sus métodos
-
2. Ejemplo
-
Tenemos una clase llamada
Personaque tiene un métodosaludar()que imprime un saludo por pantalla -
Podemos
crearunaclase anónimaqueherededePersonay redefina el métodosaludar()de la siguiente forma
// Clase Anónima
// ↓
Persona saludadorEspecial = new Persona() {
public void saludar() {
System.out.println("Hola, ¿cómo estás?");
}
};
-
Explicación
-
Estamos creando una
clase anónimaque hereda dePersonay redefine sumétodo saludar()para queimprimaun saludodiferentealoriginal- La
clase anónimasecreay seutilizaen elmismo lugary no tiene un nombre propio
- La
-
3. Ejemplo
- La clase
HelloWorldAnonymousClassesusaclases anónimasen las declaraciones de inicialización devariables localesfrenchGreetingyspanishGreetingpero usa unaclase localpara la inicialización de lavariable englishGreeting
// Clase Concreta
public class HelloWorldAnonymousClasses {
// Declaración de una interface dentro de la Clase Concreta
interface HelloWorld {
// Declaración de procedimientos
public void greet();
public void greetSomeone(String someone);
}
// Procedimiento de la clase HelloWorldAnonymousClasses
public void sayHello() {
// Clase Interna Local que hereda de la Interface HelloWorld para implementar sus método
//
// Clase Anónima
// ↓
class EnglishGreeting implements HelloWorld {
// Atributo Local
String name = "world";
// Procedimiento de la Clase HelloWorldAnonymousClasses
public void greet() {
greetSomeone("world");
}
// Procedimiento de la Clase HelloWorldAnonymousClasses
public void greetSomeone(String someone) {
name = someone;
System.out.println("Hello " + name);
}
}
// Instanciación de la clase HelloWorld
HelloWorld englishGreeting = new EnglishGreeting();
// Instanciación de la "Clase Anónima HelloWorld"
// ↓
HelloWorld frenchGreeting = new HelloWorld() {
// Atributo local
String name = "tout le monde";
// Procedimiento de la Clase HelloWorldAnonymousClasses
public void greet() {
greetSomeone("tout le monde");
}
// Procedimiento de la Clase HelloWorldAnonymousClasses
public void greetSomeone(String someone) {
name = someone;
System.out.println("Salut " + name);
}
};
// Declaración de la "Interface" convertida en "Clase Anónima"
HelloWorld spanishGreeting = new HelloWorld() {
// Atributo local
String name = "mundo";
// Procedimiento implementando desde la Interface - Clase Anónima
public void greet() {
greetSomeone("mundo");
}
// Procedimiento implementando desde la Interface - Clase Anónima
public void greetSomeone(String someone) {
name = someone;
System.out.println("Hola, " + name);
}
};
// Instanciaciones
englishGreeting.greet();
frenchGreeting.greetSomeone("Fred");
spanishGreeting.greet();
}
public static void main(String... args) {
HelloWorldAnonymousClasses myApp = new HelloWorldAnonymousClasses();
myApp.sayHello();
}
}
4. Ejemplo
-
Clase anónimausado en unainterface gráfica de usuario (GUI)- Crea
frame/marcoque contiene un botón que diga'Hello World'
- Crea
-
Invocación del método
btn.setOnAction()especifica lo que sucede cuando se pulsa el botónHello World -
Métodorequiere un objeto de tipoEventHandler<ActionEvent> -
La
interfaz EventHandler<ActionEvent>contiene solo un método llamadohandle -
En lugar de implementar este método con una
nueva clase- Ejemplo usa una
expresióndeclase anónima
- Ejemplo usa una
-
Observe que esta
expresiónes elargumentopasado al métodobtn.setOnAction -
Debido a que la
interfaz EventHandler<ActionEvent>contiene solo un método puede usar unaexpresión lambdaen lugar de unaexpresión de clase anónima -
Las
clases anónimasson ideales para implementar unainterfazque contiene dos o másmétodos
import javafx.event.ActionEvent;
import javafx.event.EventHandler;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.layout.StackPane;
import javafx.stage.Stage;
public class HelloWorld extends Application {
public static void main(String[] args) {
launch(args);
}
@Override
public void start(Stage primaryStage) {
primaryStage.setTitle("Hello World!");
Button btn = new Button();
btn.setText("Say 'Hello World'");
// AQUÍ SE DECLARA : Clase Anónima
// ↓
btn.setOnAction(new EventHandler<ActionEvent>() {
@Override
public void handle(ActionEvent event) {
System.out.println("Hello World!");
}
});
StackPane root = new StackPane();
root.getChildren().add(btn);
primaryStage.setScene(new Scene(root, 300, 250));
primaryStage.show();
}
}
5. Ejemplo
-
Personalización de controles de interfaz de usuario
-
El crea un campo de texto que solo acepta valores numéricos
-
Redefine la
implementaciónpredeterminada de laclase TextFieldcon unaClase Anónimareemplazando losmétodos replaceText()yreplaceSelection()heredados de laclase TextInputControl
import javafx.application.Application;
import javafx.event.ActionEvent;
import javafx.event.EventHandler;
import javafx.geometry.Insets;
import javafx.scene.Group;
import javafx.scene.Scene;
import javafx.scene.control.*;
import javafx.scene.layout.GridPane;
import javafx.scene.layout.HBox;
import javafx.stage.Stage;
public class CustomTextFieldSample extends Application {
final static Label label = new Label();
@Override
public void start(Stage stage) {
Group root = new Group();
Scene scene = new Scene(root, 300, 150);
stage.setScene(scene);
stage.setTitle("Text Field Sample");
GridPane grid = new GridPane();
grid.setPadding(new Insets(10, 10, 10, 10));
grid.setVgap(5);
grid.setHgap(5);
scene.setRoot(grid);
final Label dollar = new Label("$");
GridPane.setConstraints(dollar, 0, 0);
grid.getChildren().add(dollar);
final TextField sum = new TextField() {
@Override
public void replaceText(int start, int end, String text) {
if (!text.matches("[a-z, A-Z]")) {
super.replaceText(start, end, text);
}
label.setText("Enter a numeric value");
}
@Override
public void replaceSelection(String text) {
if (!text.matches("[a-z, A-Z]")) {
super.replaceSelection(text);
}
}
};
sum.setPromptText("Enter the total");
sum.setPrefColumnCount(10);
GridPane.setConstraints(sum, 1, 0);
grid.getChildren().add(sum);
Button submit = new Button("Submit");
GridPane.setConstraints(submit, 2, 0);
grid.getChildren().add(submit);
// Clase Anónima
// ↓
submit.setOnAction(new EventHandler<ActionEvent>() {
@Override
public void handle(ActionEvent e) {
label.setText(null);
}
});
GridPane.setConstraints(label, 0, 1);
GridPane.setColumnSpan(label, 3);
grid.getChildren().add(label);
scene.setRoot(grid);
stage.show();
}
public static void main(String[] args) {
launch(args);
}
}
Deja un comentario