Resumen OCP(SCJP): Capítulo 8. Inner Class

por | julio 9, 2013

CLASES INTERNAS

Dentro de la clase externa se puede instanciar una clase interna así:

MyInner mi = new MyInner();

Desde fuera de la clase externa se puede instanciar la clase interna así:

MyOuter mo = new MyOuter();
MyOuter.MyInner inner = mo.new MyInner();
//o tambien
MyOuter.MyInner inner = new MyOuter().new MyInner();

Ejemplo Inner Class tratando de acceder a una variable global externa, instancias y más.

class MyOuter {
   private String variableGlobalOuter = "outter";

   public void hacerInner() {
      MyInner mi = new MyInner();
      mi.seeInner();
   }

   //aqui si se permite clase private o final
   class MyInner {

      void seeInner() {
         System.out.println("variableGlobalOuter: " +variableGlobalOuter);
         System.out.println("Ref to Outer: " + MyOuter.this);
         System.out.println("Ref to Inner: "+this);
      }
   }

   static class MyInnerEstatico {
       void verEstatico() {//llamar a variableGlobalOuter no vale
       System.out.println("variableGlobalOuter: "/*+variableGlobalOuter*/);
   }
}

   public static void main(String[] args) {
      MyOuter o = new MyOuter();
      o.hacerInner();		

      //instancia inner class
      MyInner i = new MyOuter().new MyInner();

      //instancia inner class static
      MyInnerEstatico mie = new MyOuter.MyInnerEstatico();
   }
}

CLASES INTERNAS EN MÉTODOS LOCALES

  • Los únicos modificadores que pueden aplicar a una clase interna local son abstract o final.
  • Una clase interna local que está definida dentro un método, solamente puede ser instanciada dentro del método donde dicha clase interna es creada.

Ejemplo de una Clase Interna dentro de un Metodo Local, declaracion después de la clase interna, acceso a la variable de metodo final y más.

public class MyOuter2 {
    
    //metodo que contiene una clase
    //Method-Local Inner Classes
    public void metodoConClaseInterna() {
        
        //Cannot refer to a non-final variable.
         final String variableDeMetodo = "variable de metodo local";
        
        //only abstract or final is permitted, o default(sin modificador)
        final class ClaseInternaDentroMetodo {
            public void verInner() {
                System.out.println("La variable variableDeMetodo " +
                        "tiene que ser FINAL, si no es asi, " +
                        "no compila (Cannot refer to a non-final" +
                        " variable): " +variableDeMetodo);
            }
        }
        
        //la instancia de la clase interna en un metodo
        //debe ir despues de la clase inner NO antes
        ClaseInternaDentroMetodo ci = new ClaseInternaDentroMetodo();
        ci.verInner();
    }
    
    public static void main(String[] args) {
        MyOuter2 o2 = new MyOuter2();
        o2.metodoConClaseInterna();

    }
}

CLASES INTERNAS ANÓNIMAS

  • A causa del polimorfismo, los únicos métodos que se pueden invocar de una clase interna anónima son los métodos pertenecientes al supertipo o interface que implementa.

A continuación un ejemplo:

public class OuterPopCorn {

    void metodoOuterPopCorn() {
        System.out.println("Metodo de la clase externa OuterPopCorn");
    }

    class InnerFood {
         OuterPopCorn instanciaOuter = new OuterPopCorn() {

            @Override
            void metodoOuterPopCorn() {//sobreescribiendo el metodo de la
                                       //clase externa OuterPopCorn
                System.out.println("ANONIMO!");
            }

//            @Override no compila por la anotacion ya que el
            //este metodo no esta definido en la clase OuterPopCorn
            void metodoNoDefinidoEnPopCorn() {//genera warning
                System.out.println("Metodo que no existen en la" +
                        "clase externa OuterPopCorn. Este metodo" +
                        "no puede ser accedido.(Desde afuera)");
            }
        };

        public void metodoInnerFood() {
            instanciaOuter.metodoOuterPopCorn();
            
            //no compila is undefined for the type OuterPopCorn
            //instanciaOuter.metodoNoDefinidoEnPopCorn();
        }
    }

    public static void main(String[] args) {
        InnerFood instanciaInner = new OuterPopCorn().new InnerFood();
        instanciaInner.instanciaOuter.metodoOuterPopCorn();
        instanciaInner.metodoInnerFood();
        
        //no compila is undefined for the type PopCorn
//        instanciaInner.instanciaOuter.metodoNoDefinidoEnPopCorn();
    }
}

CLASES ANIDADAS (CLASES INTERNAS ESTÁTICAS)

Como la clase anidada es estática, esta no comparte ninguna relación con la instancia de la clase externa. De hecho, no se necesita una instancia de la clase externa para instanciar una clase anidada

Una clase anidada no puede acceder a los miembros no estáticos de la clase externa, ya que no posee una referencia implícita a ella.

EOF