dentro de otras clases que las contienen No son estticas No son annimas class MyOuter {
class MyInner {
} }
Clases Internas class MyOuter { private int x = 7; //definicion de una clase interna class MyInner { public void seeOuter() { System.out.println("Outer x is " + x); } } // se cierra la definicin de la clase interna } // se cierra la definicin de la clase externa
Las Clases internas tienen acceso a todos los elementos privados de la clase que lo contiene. Instanciando clases internas Las clases internas pueden ser instanciadas dentro de aquellas clases que las contienen. class MyOuter { private int x = 7; public void makeInner() { MyInner in = new MyInner(); // se instancia una clase interna in.seeOuter(); } class MyInner { public void seeOuter() { System.out.println("Outer x is " + x); } } }
Instanciando clases internas Se pueden instanciar separadamente las clases internas de las clases que la contienen de la siguiente forma. public static void main(String[] args) {
MyOuter mo = new MyOuter(); //Intancia de la clase contenedora
MyOuter.MyInner inner = mo.new MyInner();
inner.seeOuter(); } O lo que es lo mismo public static void main(String[] args) {
MyOuter.MyInner inner = new MyOuter().new MyInner();
inner.seeOuter(); }
Referenciando class MyOuter { private int x = 7; public void makeInner() { MyInner in = new MyInner(); in.seeOuter(); } class MyInner { public void seeOuter() { System.out.println("Outer x is " + x); System.out.println("Inner class ref is " + this); System.out.println("Outer class ref is " + MyOuter.this); } } public static void main (String[] args) { MyOuter.MyInner inner = new MyOuter().new MyInner(); inner.seeOuter(); } } // resultado Outer x is 7 Inner class ref is MyOuter$MyInner@113708 Outer class ref is MyOuter@33f1d7
Modificadores de miembros Se pueden utilizar para las clases internas los cualquier modificador de miembro de la clase. final abstract public private protected staticpero estatic hace a la clase un clase anidada esttica y no una clase interna Clases internas locales a mtodos Las clases internas tambin pueden ser declaradas dentro de mtodos class MyOuter2 { private String x = "Outer2"; void doStuff() { class MyInner { public void seeOuter() { System.out.println("Outer x is " + x); } // cierra el metodo de la clase interna } // cierra la clase interna } // cierra el mtodo de la clase externa } // cierra la clase externa
Clases internas locales a mtodos Un ejemplo de uso de la clase es el siguiente class MyOuter2 { private String x = "Outer2"; void doStuff() { class MyInner { public void seeOuter() { System.out.println("Outer x is " + x); } //cierra el metodo de la clase interna } // cierra la definicion de la clase interna MyInner mi = new MyInner(); // esta linea debe ir despues // de la declaracion de la clase interna mi.seeOuter(); } // cierra el metodo duStuff() } // cierra la clase externa
Clases Internas locales a metodos Las clases internas locales no pueden ser instanciadas fuera del mtodo donde se las declararon por ningn motivo. Las clases internas locales pueden ser instanciadas solo despus de la declaracin de la clase. Las clases internas locales no puede utilizar las variables locales a los mtodos en los cuales fueron declaradas a menos que esta variables sean marcadas como finales. Clases Internas locales a metodos class MyOuter2 { private String x = "Outer2"; void doStuff() { final String z = "local variable"; class MyInner { public void seeOuter() { System.out.println("Outer x is " + x); System.out.println("Local variable z is " + z); // compila solo porque z es final
} // close inner class method } // close inner class definition } // close outer class method doStuff() } // close outer class
Clases Internas Anonimas Es raro pero puede aparecer esta sintaxis , en verde la clase annima que hereda de Popcorn y sobre escribe pop(). class Popcorn { public void pop() { System.out.println("popcorn"); } } class Food { Popcorn p = new Popcorn() { public void pop() { System.out.println("anonymous popcorn"); } }; }
Clases Internas Anonimas class Popcorn { public void pop() { System.out.println("popcorn"); } } class Food { Popcorn p = new Popcorn() { public void sizzle() { System.out.println("anonymous sizzling popcorn"); } public void pop() { System.out.println("anonymous popcorn"); } }; public void popIt() { p.pop(); // OK, Popcorn tiene un metodo pop() p.sizzle(); // Error Popcorn no tiene un metodo sizzle; } } Solo se puede llamar a metodos que contenga la clase superior a la clase anonima. Clase Internas Annimas Las clases annimas pueden estar basadas en interfaces as tenemos lo que se llaman clases annimas implementadoras por ejemplo interface Cookable { public void cook(); } class Food { Cookable c = new Cookable() {
public void cook() { System.out.println("anonymous cookable implementer"); } }; }
Clase Anonima por parametro Se puede crear una clase annima y pasar su instancia directamente en un mtodo como lo que sigue. class MyWonderfulClass { void go() { Bar b = new Bar(); b.doStuff(new Foo() { public void foof() { System.out.println("foofy"); } // se termina el metodo foof }); // cierre de la clase anonima y del metodo doStuff() } // cierre de go() } // cierre de clase interface Foo { void foof(); } class Bar { void doStuff(Foo f) { } } Clases estticas anidadas Son clase internas que tienen el identificador static. class BigOuter { static class Nest {void go() { System.out.println("hi"); } } } class Broom { static class B2 {void goB2() { System.out.println("hi 2"); } }
public static void main(String[] args) { BigOuter.Nest n = new BigOuter.Nest(); //Instanciacion de la clase anidada Nest n.go(); B2 b2 = new B2(); //Instanciacion de la clase anidad B2 b2.goB2(); }