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
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
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
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

Yves Catalog

  • 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ónde 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 - claseanó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