SCJP, Clase 8: Inner Classes
-
Upload
flekoso -
Category
Technology
-
view
4.735 -
download
2
description
Transcript of SCJP, Clase 8: Inner Classes
![Page 1: SCJP, Clase 8: Inner Classes](https://reader035.fdocuments.us/reader035/viewer/2022062307/5563a61fd8b42aae0d8b4ee4/html5/thumbnails/1.jpg)
SCJP 6 Clase 8 – Inner Classes
Ezequiel Aranda
Sun Microsystems Campus Ambassador
![Page 2: SCJP, Clase 8: Inner Classes](https://reader035.fdocuments.us/reader035/viewer/2022062307/5563a61fd8b42aae0d8b4ee4/html5/thumbnails/2.jpg)
Disclaimer & Acknowledgments
> Even though Ezequiel Aranda is a full-time employee of Sun Microsystems, the contents here are created as his own personal endeavor and thus does not reflect any official stance of Sun Microsystems.
> Sun Microsystems is not responsible for any inaccuracies in the contents.
> Acknowledgments – The slides of this presentation are made from “SCJP Unit 8” by Warit Wanwithu and Thanisa Kruawaisayawan and SCJP Workshop by P. Srikanth.
> This slides are Licensed under a Creative Commons Attribution – Noncommercial – Share Alike 3.0 > http://creativecommons.org/licenses/by-nc-sa/3.0/
![Page 3: SCJP, Clase 8: Inner Classes](https://reader035.fdocuments.us/reader035/viewer/2022062307/5563a61fd8b42aae0d8b4ee4/html5/thumbnails/3.jpg)
AGENDA
> Generics Vs. Arrays
> Clases internas > Clases internas “regulares”
> Clases internas locales a un método
> Clases internas anónimas
> Clases estáticas anidadas
![Page 4: SCJP, Clase 8: Inner Classes](https://reader035.fdocuments.us/reader035/viewer/2022062307/5563a61fd8b42aae0d8b4ee4/html5/thumbnails/4.jpg)
Generics Vs. Arrays
Animal
<<abs>> checkup()
Bird Cat Dog
![Page 5: SCJP, Clase 8: Inner Classes](https://reader035.fdocuments.us/reader035/viewer/2022062307/5563a61fd8b42aae0d8b4ee4/html5/thumbnails/5.jpg)
Generics Vs. Arrays (II)
public void checkAnimals(ArrayList<Animal> animals){
for(Animal a : animals) {
a.checkup();
}
}
doc.checkAnimals(dogs); // dogs: List<Dog>
doc.checkAnimals(cats); // cats: List<Cat>
doc.checkAnimals(birds); // birds: List<Bird>
> ¿Porqué no funciona?
> ¿Cómo solucionarlo?
![Page 6: SCJP, Clase 8: Inner Classes](https://reader035.fdocuments.us/reader035/viewer/2022062307/5563a61fd8b42aae0d8b4ee4/html5/thumbnails/6.jpg)
Generics Vs. Arrays (III)
Animal[] animals = new Animal[3];
animals[0] = new Cat();
animals[1] = new Dog();
List<Animal> animals = new ArrayList<Animal>();
animals.add(new Cat()); // OK
animals.add(new Dog()); // OK
> Esto funciona con ambos, Arrays y Generics.
![Page 7: SCJP, Clase 8: Inner Classes](https://reader035.fdocuments.us/reader035/viewer/2022062307/5563a61fd8b42aae0d8b4ee4/html5/thumbnails/7.jpg)
Generics Vs. Arrays (IV)
> Funciona siempre: public void addAnimal(Animal[] animals) {
animals[0] = new Dog(); Animal[]
}
> Funciona a veces: public void addAnimal(ArrayList<Animal> animals) {
animals.add(new Dog());
}
![Page 8: SCJP, Clase 8: Inner Classes](https://reader035.fdocuments.us/reader035/viewer/2022062307/5563a61fd8b42aae0d8b4ee4/html5/thumbnails/8.jpg)
Generics Vs. Arrays (V)
> La razón por la cual es peligroso pasar como parámetro una colección de un subtipo es porque podríamos agregar algo erróneo en la colección (o en el Array).
![Page 9: SCJP, Clase 8: Inner Classes](https://reader035.fdocuments.us/reader035/viewer/2022062307/5563a61fd8b42aae0d8b4ee4/html5/thumbnails/9.jpg)
Generics Vs. Arrays (VI)
public void foo() {
Dog[] dogs = {new Dog(), new Dog()}; addAnimal(dogs);
}
public void addAnimal(Animal[] animals) {
animals[0] = new Dog();
}
> Esto funciona perfectamente, y es correcto.
![Page 10: SCJP, Clase 8: Inner Classes](https://reader035.fdocuments.us/reader035/viewer/2022062307/5563a61fd8b42aae0d8b4ee4/html5/thumbnails/10.jpg)
Generics Vs. Arrays (VII)
public void foo() {
Cat[] cats = {new Cat(), new Cat()}; addAnimal(cats);
}
public void addAnimal(Animal[] animals) {
animals[0] = new Dog();
}
> Acabamos de poner un gato en un Array de perros.
![Page 11: SCJP, Clase 8: Inner Classes](https://reader035.fdocuments.us/reader035/viewer/2022062307/5563a61fd8b42aae0d8b4ee4/html5/thumbnails/11.jpg)
Generics Vs. Arrays (VIII)
> Sin embargo, y a diferencia que realizando el mismo ejemplo con colecciones parametrizadas, el código anterior, compila
> Lo que permite que compile es la existencia de la excepción ArrayStoreException, que previene que se de el problema visto anteriormente en tiempo de ejecución.
![Page 12: SCJP, Clase 8: Inner Classes](https://reader035.fdocuments.us/reader035/viewer/2022062307/5563a61fd8b42aae0d8b4ee4/html5/thumbnails/12.jpg)
Generics Vs. Arrays (IX)
> Pero no existe un equivalente a esta excepción para colecciones, debido a que las parametrizaciones se eliminan en tiempo de ejecución.
> Es decir, la JVM conoce el tipo de los Arrays en tiempo de ejecución, pero no el tipo de una colección.
![Page 13: SCJP, Clase 8: Inner Classes](https://reader035.fdocuments.us/reader035/viewer/2022062307/5563a61fd8b42aae0d8b4ee4/html5/thumbnails/13.jpg)
Codificando una inner class “regular”
> Llamamos regulares a las clases internas que no son: > Estáticas
> Locales a un método
> Anónimas
> Una inner class regular no puede tener declaraciones estáticas de ningún tipo
> La única forma de acceder a la clase interna es a través de una instancia de la clase externa.
![Page 14: SCJP, Clase 8: Inner Classes](https://reader035.fdocuments.us/reader035/viewer/2022062307/5563a61fd8b42aae0d8b4ee4/html5/thumbnails/14.jpg)
class MyOuter {
private int x = 7;
class MyInner {
public void seeOuter() {
System.out.println("Outer x is " + x); }}
}
> Este código es perfectamente legal. Nótese que la clase interna esta accediendo a un miembro privado de la clase externa. Esto es correcto, dado que la clase interna es un miembro de la clase externa también.
![Page 15: SCJP, Clase 8: Inner Classes](https://reader035.fdocuments.us/reader035/viewer/2022062307/5563a61fd8b42aae0d8b4ee4/html5/thumbnails/15.jpg)
Instanciando una clase interna > Desde el interior de la clase externa:
MyInner mi = new MyInner();
> Desde el exterior de la clase externa (incluyendo código de métodos estáticos dentro de la clase externa): MyOuter.MyInner
> Para instanciar un objeto de la clase interna debemos usar una referencia a la clase externa: obj = new MyOuter().new MyInner();
u outerObjRef.new MyInner();
![Page 16: SCJP, Clase 8: Inner Classes](https://reader035.fdocuments.us/reader035/viewer/2022062307/5563a61fd8b42aae0d8b4ee4/html5/thumbnails/16.jpg)
this
> “this” es una referencia al objeto que esta en ejecución actualmente. public void myMethod() {
MyClass mc = new MyClass();
mc.doStuff(this);
}
![Page 17: SCJP, Clase 8: Inner Classes](https://reader035.fdocuments.us/reader035/viewer/2022062307/5563a61fd8b42aae0d8b4ee4/html5/thumbnails/17.jpg)
Haciendo referencia a la instancia de la clase interna/ externa desde la clase interna
class MyOuter {
private int x = 7;
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);
} } }
![Page 18: SCJP, Clase 8: Inner Classes](https://reader035.fdocuments.us/reader035/viewer/2022062307/5563a61fd8b42aae0d8b4ee4/html5/thumbnails/18.jpg)
Clases internas locales a un método
class MyOuter2 {
private String x = "Outer2";
void doStuff() {
class MyInner {
public void seeOuter() {
System.out.println("Outer x is " + x);
}
}
MyInner mi = new MyInner();
mi.seeOuter(); }
}
![Page 19: SCJP, Clase 8: Inner Classes](https://reader035.fdocuments.us/reader035/viewer/2022062307/5563a61fd8b42aae0d8b4ee4/html5/thumbnails/19.jpg)
Que puede y que no puede hacer una clase local a un método
> Definiendo una clase interna dentro de un método, solo podremos crear objetos de esa clase dentro del método.
> Puede ser una clase abstracta.
> No puede tener métodos o atributos estáticos salvo que la clase interna sea estática también.
![Page 20: SCJP, Clase 8: Inner Classes](https://reader035.fdocuments.us/reader035/viewer/2022062307/5563a61fd8b42aae0d8b4ee4/html5/thumbnails/20.jpg)
Que puede y que no puede hacer una clase local a un método (II)
> Puede acceder a las variables de la clase externa.
> No puede acceder a las variables locales al método. > Salvo que sean declaradas “final”
> Los únicos modificadores que podemos aplicar a una clase interna local a un método son “abstract” y “final”. > Como siempre, no podemos aplicar los dos al
mismo tiempo.
![Page 21: SCJP, Clase 8: Inner Classes](https://reader035.fdocuments.us/reader035/viewer/2022062307/5563a61fd8b42aae0d8b4ee4/html5/thumbnails/21.jpg)
Que puede y que no puede hacer una clase local a un método (III)
class MyOuter2 {
private String x = "Outer2";
void doStuff() {
String z = "local variable";
class MyInner {
public void seeOuter() {
System.out.println("Outer x is " + x);
System.out.println("Local variable z is"+ z);
// Esto no compila. Dado que se accede a z desde la clase interna, z debe ser declarada final.
} } } }
![Page 22: SCJP, Clase 8: Inner Classes](https://reader035.fdocuments.us/reader035/viewer/2022062307/5563a61fd8b42aae0d8b4ee4/html5/thumbnails/22.jpg)
Clases internas anónimas class Popcorn { public void pop() { System.out.println("popcorn"); } } class Food { Popcorn p = new Popcorn() { public void pop() { System.out.println("anonymous popcorn"); } }; // debe colocarse un punto y coma aquí }
> La variable p no hace referencia a una instancia de Popcorn, sino a una instancia de una subclase anónima de Popcorn.
![Page 23: SCJP, Clase 8: Inner Classes](https://reader035.fdocuments.us/reader035/viewer/2022062307/5563a61fd8b42aae0d8b4ee4/html5/thumbnails/23.jpg)
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 p.sizzle(); //KO }}
¿Porqué no funciona?
![Page 24: SCJP, Clase 8: Inner Classes](https://reader035.fdocuments.us/reader035/viewer/2022062307/5563a61fd8b42aae0d8b4ee4/html5/thumbnails/24.jpg)
Clases internas anónimas: implementando una interfaz
interface Cookable {
public void cook();
}
class Food {
Cookable c = new Cookable() {
public void cook() {
System.out.println("anonymous cookable implementer");
}
};
}
Nota: no existe un mecanismo para implementar mas de una interfaz de esta forma
![Page 25: SCJP, Clase 8: Inner Classes](https://reader035.fdocuments.us/reader035/viewer/2022062307/5563a61fd8b42aae0d8b4ee4/html5/thumbnails/25.jpg)
class MyWonderfulClass { void go() { Bar b = new Bar(); b.doStuff(new Foo() { public void foof() { System.out.println("foofy"); } // fin foof }); //fin inner class y declaración del método } // fin go() } // fin class interface Foo { void foof(); } class Bar { void doStuff(Foo f) { } }
Clases internas anónimas: clases definidas en
argumentos
![Page 26: SCJP, Clase 8: Inner Classes](https://reader035.fdocuments.us/reader035/viewer/2022062307/5563a61fd8b42aae0d8b4ee4/html5/thumbnails/26.jpg)
Clases estáticas anidadas 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(); n.go(); B2 b2 = new B2(); b2.goB2(); }}
![Page 27: SCJP, Clase 8: Inner Classes](https://reader035.fdocuments.us/reader035/viewer/2022062307/5563a61fd8b42aae0d8b4ee4/html5/thumbnails/27.jpg)
Clases estáticas anidadas (II)
> Las clases no son exactamente “estáticas”. No existe tal cosa.
> En este caso el modificador “static” indica que la clase interna es un miembro estático de la clase externa.
> Esto quiere decir que podemos acceder al mismo sin la necesidad de crear una instancia de la clase externa.
> No puede acceder a los miembros de la clase externa de la misma forma que lo haría una clase interna (exceptuando a los estáticos, claro está).
![Page 28: SCJP, Clase 8: Inner Classes](https://reader035.fdocuments.us/reader035/viewer/2022062307/5563a61fd8b42aae0d8b4ee4/html5/thumbnails/28.jpg)
Preguntas