1. Clases internas - Java 1.1
• Permiten el anidamiento de clases
• Definición de una clase dentro de otra
• Definición de una clase localmente a un bloque de código
• Propósito
Clases internas • Agrupación de clases relacionadas
• Control de visibilidad de las clases
• Proximidad entre la definición y el uso de las clases
• Definición de clases simples de ayuda o adaptación
❏ Nuevo modelo de eventos de Java 1.1 (AWT y Swing)
• Código más claro que evita el exceso de clases muy
pequeñas que no necesitan conocer los usuarios de un
paquete
Java BFM 1 Java BFM 2
Tipos de clases internas Clases e interfaces de alto nivel
• Clases e interfaces anidadas de alto nivel • Clases o interfaces estáticos anidados dentro de otra clase
• También se denominan clases internas estáticas (clase externa, contenedora o encapsuladora)
• Clases internas • Deben declararse de tipo static
• Clases miembro • Sólo se pueden anidar dentro de clases normales o de
• Clases locales clases internas de alto nivel
• Clases anónimas • No es necesario un objeto de la clase externa para crear
un objeto de la clase interna estática
• Especificación del tipo del objeto
❏ NombreClaseExterna.NombreClaseInterna
• Desde la clase estática interna sólo se pueden acceder a
los miembros estáticos de la clase externa
• Nombrado fichero .class
❏ NombreClaseExterna$NombreClaseInterna
Java BFM 3 Java BFM 4
2. Ejemplo - modificación de Eckel Clases miembro
// Para poder ejecutar la prueba hay que poner en • Clase interna definida como miembro (no static) de otra
// Settings, Java Target, Main Class : MarcoPrueba$Probador clase contenedora
public class MarcoPrueba { • Pueden declararse como privadas o protegidas (esto no impide
static int i= 5; su acceso desde la clase contenedora)
public MarcoPrueba() {};
void metodo() {System.out.println(" dentro de metodo de MarcoPrueba");} • Cada instancia de una clase miembro se asocia
internamente a una instancia de la clase contenedora
// clase interna estática que prueba el funcionamiento de la clase externa
public static class Probador { • Tiene acceso completo y directo a la clase externa (incluido
public static void main(String args[]) { miembros private)
// acceso al miembro estático de la clase externa ❏ Simplifica el código
System.out.println( "Dentro de probador" + i);
MarcoPrueba marco= new MarcoPrueba(); • No puede tener miembros estáticos
marco.metodo(); • No pueden tener nombres comunes con la clase externa
}
❏ Conflicto de nombrado
} // fin de probador
} • No es posible crear un objeto de la clase interna sin tener
Java BFM 5
un objeto de la clase contenedora
Java BFM 6
Ejemplo - clase adaptadora Enumerador Ejemplo - prueba de la clase
public class PilaArray { public class Prueba {
Object array[]; public static void main(String args[]) {
int cima = 0; PilaArray pila;
pila = new PilaArray(5);
PilaArray(int tamanoLimiteFijo) {array = new Object[tamanoLimiteFijo]; }
// rellenamos la pila
public void apila(Object item) { array[cima++] = item; }
public Object desapila() { return array[--cima]; }
for (int i=0; i<5; i++) {
public boolean estaVacia() { return cima == 0; } String cad = "hola" + i;
// clase adaptadora que queda oculta pila.apila(cad);
class Enumerador implements java.util.Enumeration { }
int cont = cima;
public boolean hasMoreElements() { return cont > 0; } // creamos un enumerador sobre la pila y
public Object nextElement() { // lo utilizamos para listar sus elementos
if (cont == 0)
java.util.Enumeration enumerador;
throw new NoSuchElementException("Pila en Array");
return array[--cont];
enumerador = pila.elementos();
} while (enumerador.hasMoreElements()) {
} // Enumerador String cad = (String) enumerador.nextElement();
// devuelve un enumerador sobre la pila System.out.println( cad );
public java.util.Enumeration elementos() { }
return new Enumerador(); }}
}}
Java BFM 7 Java BFM 8
3. Clases miembro Clases locales
• Nueva sintaxis de this, new y super • Clase interna definida dentro de un bloque de código
• Referencia al objeto de la clase contenedora • Sólo son visibles y utilizables dentro del bloque de código en
❏ NombreClaseContenedora.this el que se encuentran definidas
• Creación de un objeto de una clase interna • Pueden usar variables locales y parámetros de método
❏ referenciaObjetoContenedor.new NombreClaseInterna() declarados como final
• En herencia de una clase interna ❏ Se evitan problemas de sincronización (inconsistencias)
❏ dentro del constructor de la clase especializada
referenciaObjetoContenedor.super()
• No pueden incluir un modificador de acceso ni ser estáticas
• Uso extensivo en el nuevo tratamiento de eventos de Java
// pruebas con new 1.1
// fallaría si la clase enumerador se hubiera declarado privada
PilaArray.Enumerador enum2 = pila.new Enumerador(); • Creación de clases de ayuda o adaptación que no estén
while (enum2.hasMoreElements()) { disponibles públicamente (inaccesibles)
String cad = (String) enum2.nextElement();
System.out.println( cad );
}
Java BFM 9 Java BFM 10
Ejemplo - clase local Clases anónimas
// definicion de una clase local que implementa un enumerador • Clase interna local sin nombre
Enumeration miEnumerador (final Object array[]) {
class ClaseLocal implements java.util.Enumeration { • Se define e instancia en una sola operación
int cont = 0;
• Sólo puede existir una instancia de una clase anónima
public boolean hasMoreElements() {
return cont < array.length; • Una clase anónima puede ser incluida en una expresión
} java
public Object nextElement() {
if (cont == array.length) • Los constructores anónimos deben ser sencillos para evitar
throw new NoSuchElementException("Pila en Array"); la excesiva anidación de código
return array[cont++];
} • Muy utilizado en adaptadores de clase
}
return new ClaseLocal();
• Añadir comportamiento a objetos que ya tienen nombre
} (AWT, Swing)
// devuelve un enumerador sobre la pila • Escritura de pequeños “callbacks” encapsulados
public java.util.Enumeration elementos() {
return miEnumerador(array); (enumeradores, iteradores, …)
}
Java BFM 11 Java BFM 12
4. Ejemplo - clase anónima
// devuelve un enumerador sobre la pila mediante una clase anónima
public Enumeration elementos() {
return new Enumeration() {
int cont = cima;
public boolean hasMoreElements() {
return cont > 0;
}
public Object nextElement() {
if (cont == 0)
throw new NoSuchElementException("Pila en Array");
return array[--cont];
}
};
}
Java BFM 13