Sei sulla pagina 1di 62

SCJP 6

Clase 1.5 Ejemplos de enum

Ezequiel Aranda Sun Microsystems Campus Ambassador

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

Pre Java 5.0


>Antes de Java 5, la forma estndar de representar una enumeracin, era utilizar el pattern int Enum
public public public public static static static static final final final final int int int int SEASON_WINTER SEASON_SPRING SEASON_SUMMER SEASON_FALL = = = = 0; 1; 2; 3;

>Este pattern tena muchos problemas (no tenan namespace, no eran typesafe, brittleness, informacin nula al imprimirlos).

Java 5.0
> Soporta enums como un tipo. > Son una clase. > Por lo tanto, pueden tener mtodos y variables, implementar interfaces, y ms. > Proveen implementaciones de los mtodos heredados de Object. > Son Comparables y Serializables.

Ejemplo Mazo de cartas


import java.util.*; public class Card { public enum Rank { DEUCE, THREE, FOUR, FIVE, SIX, SEVEN, EIGHT, NINE, TEN, JACK, QUEEN, KING, ACE } public enum Suit { CLUBS, DIAMONDS, HEARTS, SPADES } private final Rank rank; private final Suit suit; private Card(Rank rank, Suit suit) { this.rank = rank; this.suit = suit; }

public Rank rank() { return rank; } public Suit suit() { return suit; } public String toString() { return rank + " de" + suit; } private static final List<Card> protoDeck = new ArrayList<Card>(); // Initializa el mazo static { for (Suit suit : Suit.values()) for (Rank rank : Rank.values()) protoDeck.add(new Card(rank, suit)); } public static ArrayList<Card> newDeck() { return new ArrayList<Card>(protoDeck); // Retorna una copia del mazo. } }

Ejemplo Mazo de cartas (II)


> toString() de Card toma ventaja de toString de Rank y Suit. > El constructor de Card toma un Rank y un Suit. > values() retorna un array que contiene los elementos del enum.

Ejemplo Repartir las cartas


import java.util.*; public class Deal { public static void main(String args[]) { int numHands = Integer.parseInt(args[0]); int cardsPerHand = Integer.parseInt(args[1]); List<Card> deck = Card.newDeck(); Collections.shuffle(deck); for (int i=0; i < numHands; i++) System.out.println(deal(deck, cardsPerHand)); } public static ArrayList<Card> deal(List<Card> deck, int n) { int deckSize = deck.size(); List<Card> handView = deck.subList(deckSize-n, deckSize); ArrayList<Card> hand = new ArrayList<Card>(handView); handView.clear(); return hand; } }

Ejecucin de Deal
$ java Deal 4 5 [FOUR of HEARTS, NINE of DIAMONDS, QUEEN of SPADES, ACE of SPADES, NINE of SPADES] [DEUCE of HEARTS, EIGHT of SPADES, JACK of DIAMONDS, TEN of CLUBS, SEVEN of SPADES] [FIVE of HEARTS, FOUR of DIAMONDS, SIX of DIAMONDS, NINE of CLUBS, JACK of CLUBS] [SEVEN of HEARTS, SIX of CLUBS, DEUCE of DIAMONDS, THREE of SPADES, EIGHT of CLUBS]

Agregar operaciones
public enum MERCURY VENUS EARTH MARS JUPITER SATURN URANUS NEPTUNE PLUTO Planet { (3.303e+23, (4.869e+24, (5.976e+24, (6.421e+23, (1.9e+27, (5.688e+26, (8.686e+25, (1.024e+26, (1.27e+22, 2.4397e6), 6.0518e6), 6.37814e6), 3.3972e6), 7.1492e7), 6.0268e7), 2.5559e7), 2.4746e7), 1.137e6);

private final double mass; // in kilograms private final double radius; // in meters Planet(double mass, double radius) { this.mass = mass; this.radius = radius; }

public double mass() { return mass; } public double radius() { return radius; } // universal gravitational constant (m3 kg-1 s-2) public static final double G = 6.67300E-11; public double surfaceGravity() { return G * mass / (radius * radius); } public double surfaceWeight(double otherMass) { return otherMass * surfaceGravity(); } }

Calcular nuestro peso en cualquier planeta


public static void main(String[] args) { double earthWeight = Double.parseDouble(args[0]); double mass = earthWeight/EARTH.surfaceGravity(); for (Planet p : Planet.values()) System.out.printf("Your weight on %s is %f%n", p, p.surfaceWeight(mass)); } $ java Planet 175 Your weight on MERCURY is 66.107583 Your weight on VENUS is 158.374842 Your weight on EARTH is 175.000000 Your weight on MARS is 66.279007 Your weight on JUPITER is 442.847567 Your weight on SATURN is 186.552719 Your weight on URANUS is 158.397260 Your weight on NEPTUNE is 199.207413 Your weight on PLUTO is 11.703031

SCJP 6
Clase 2 POO

AGENDA
> Encapsulamiento > Herencia (es un / tiene un) > Polimorfismo > Interfaces > Valores de retorno legales > Constructores > Mtodos y variables estticas

Encapsulamiento
> Oculta ciertos elementos de la implementacin de una clase proveyendo una interfaz pblica para los clientes. > Mantiene las variables de instancia protegidas (private). > Se utilizan mtodos de accesos pblicos, forzando su utilizacin en vez de el acceso directo a las variables de instancia (set<Propiedad>, get<Propiedad>).

Encapsulamiento
ObjetoB.Metodo1()

Datos Objeto A

Datos Objeto B

Valor de retorno

Herencia
> El lenguaje Java permite que una clase herede funcionalidad de una nica clase. > Esto se conoce como herencia simple.
Scanner Impresora Deporte

Fotocopiadora

Ftbol

Rugby

Relaciones es un
> En POO, el concepto de es un se basa en la herencia de clases o implementacin de interfaces. Es un es una forma de decir Esta cosa es un tipo de esa otra.
Auto

Auto Deportivo

Relaciones Tiene un
> Estn basadas en el uso, ms que en la herencia. En otras palabras, la clase A tiene un B si el cdigo en la clase A tiene una referencia a una instancia de la clase B. > Por ejemplo: un caballo ES UN animal y TIENE UN cabestro. Escrito en Java, sera algo como:
public class Animal {} public class Caballo extends Animal { private Cabestro miCabestro; }

Polimorfismo
> Las invocaciones polimorficas a mtodos slo aplican a mtodos de instancia. > Siempre podremos referirnos a un objeto con una variable de un tipo ms general (una superclase o interfaz). > Por lo tanto, podemos hacer cosas como: Auto a = new AutoDeportivo();

Pregunta
public class Employee{ public void printDetail(){ system.out.println(Employee); } } public class Manager extends Employee{ public String department = Marketing; public void printDetail(){ system.out.println(Manager); } }

>Si hiciramos Employee e = new Manager(), podramos usar la variable department? y que resultado tendra la llamada a e.printDetail()?

Sobrescritura de mtodos
> Siempre que tengamos una clase que herede un mtodo de una superclase, tendremos la posibilidad de sobrescribir dicho mtodo. > Salvo que tal mtodo sea final o static. > El nmero y el tipo de los argumentos DEBEN ser iguales.

Sobrescritura de mtodos (II)


> El tipo a retornar debe ser el mismo (desde Java 5.0, puede ser un subtipo del tipo retornado por el mtodo sobrescrito tipos covariantes). > No puede ser menos accesible. Un modificador ms amplio s es valido. > No debe arrojar nuevas excepciones o excepciones ms amplias que las declaradas por el mtodo sobrescrito.

Invocar la versin presente en la superclase de un mtodo sobrescrito


public class Animal { public void eat() { } public void printYourself() { // cdigo de impresin } } class Horse extends Animal { public void printYourself() { super.printYourself(); // Invocamos el cdigo //presente en Animal // Luego agregamos cdigo especfico debajo } }

Sobrecarga de mtodos
>La sobrecarga de mtodos permite reusar el mismo nombre de un mtodo en una clase, pero con una lista de argumentos diferente. >Un mtodo sobrecargado DEBE cambiar la lista de argumentos respecto del original. >Un mtodo sobrecargado PUEDE cambiar el tipo del valor de retorno respecto del original.

Sobrecarga de mtodos (II)


> Un mtodo sobrecargado PUEDE cambiar su modificador de acceso respecto del original. > Un mtodo sobrecargado PUEDE declarar nuevas o ms amplias excepciones que el original. > Un mtodo puede sobrecargarse en la misma clase o en una subclase.

Cual es el resultado de este cdigo?


class Car { } class BMW extends Car { } class UsedCar{ public void doStuff(Car System.out.println("In } public void doStuff(BMW System.out.println("In }

b) { the Car version"); b) { the BMW version");

public static void main (String [] args) { UsedCar uc= new UsedCar(); Car c = new Car(); BMW b = new BMW(); Car carRefToBMW= new BMW(); uc.doStuff(c); uc.doStuff(b); uc.doStuff(carRefToBMW); } }

En resumen
> La eleccin sobre que versin de un mtodo sobrescrito llamar, es hecha en tiempo de ejecucin, y se basa en el tipo del objeto. > Mientras que la eleccin sobre que versin de un mtodo sobrecargado llamar se basa en el tipo de la referencia del argumento que se pasa en tiempo de compilacin.

Casting de variables de referencia


> Hacia abajo:
> Manager m = (Manager) new Empleado();

> Hacia arriba:


> Empleado e = (Empleado) new Manager();
Empleado

Ingeniero

Manager

Casting de variables de referencia (II)


> El compilador es forzado a confiar en nosotros cuando hacemos un casting hacia abajo, incluso cuando est mal. > Por lo que cuando hagamos algo como:
> Manager m = (Manager) new Empleado();

El resultado ser la aparicin de una excepcin java.lang.ClassCastException en tiempo de ejecucin.

Implementando una interfaz


> Al implementar una interfaz, estamos aceptando adherirnos al contrato definido por esa interfaz. > Implica que deberemos proveer implementaciones legales de todos los mtodos definidos en tal interfaz. > Las clases que implementan una interfaz deben seguir las mismas reglas que las clases que extienden clases abstractas.

Implementando una interfaz (II)


> Proveer implementaciones no abstractas para todos los mtodos de la interfaz declarada. > Seguir todas las reglas para sobrescrituras. > Declarar solo las mismas excepciones que aquellas declaradas en el mtodo de la interfaz, o subclases de esas excepciones. > Mantener la signatura y el tipo de retorno (o un subtipo). No es necesario declarar las excepciones.

Pregunta
Interface A { void methodA(); } public class Temp implements A{ void methodA() { } }

> Compila? Por qu?

? ?

Implementando una interfaz (III)


> Cuando declaramos mtodos en una interfaz, el compilador los generar con los modificadores public abstract. > Cuando declaramos atributos en una interfaz, el compilador los generar con los modificadores static final.

Implementando una interfaz (IV)


> Por lo tanto, podremos hacer cosas como:
> abstract class Ball implements Bounceable > public class Ball implements Bounceable, Serializable, Runnable > public interface Bounceable extends MoveRunnable

Reglas respecto de interfaces


>class Foo{ } // OK >class Bar implements Foo{ } //no se puede implementar una clase >interface Baz{ } // OK >interface Fi{ } // OK >interface Fee implements Baz{ } // una interfaz no puede implementar una interfaz > interface Zee implements Foo{ } // una interfaz no puede implementar una clase > interface Zoo extends Foo{ } // una interfaz no puede extender una clase

Reglas respecto de interfaces (II)


>interface Boo extends Fi { } // OK. Una interfaz puede extender una interfaz >class Toonextends Foo, Button { } // Una clase no puede extender mltiples clases >class Zoom implements Fi, Fee { } // OK. Una clase puede extender mltiples interfaces >interface Vroom extends Fi, Fee { } // OK. Una interfaz puede extender mltiples interfaces >class Yow extends Foo implements Fi { } // OK. Pero extends debe ir primero

public abstract interface Frobnicate { public void twiddle(String s); }

> Cuales declaraciones de clase son correctas?


A. public abstract class Frob implements Frobnicate { public abstract void twiddle(String s) { } } B. public abstract class Frob implements Frobnicate { } C. public class Frob extends Frobnicate { public void twiddle(Integer i) { } } D. public class Frob implements Frobnicate { public void twiddle(Integer i) { } } E. public class Frob implements Frobnicate { public void twiddle(String i) { } public void twiddle(Integer s) { } }

Valores de retorno
> En los mtodos sobrecargados, no podemos cambiar slo el tipo de retorno.
public class Foo{ void go() { } } public class Bar extends Foo{ String go() { // No legal return null; } }

Valores de retorno (II)


> Mtodos sobrescritos A partir de Java 5, el tipo retornado en un mtodo puede ser un subtipo del tipo retornado en el mtodo (de la superclase) que este est sobrescribiendo.

Valores de retorno (III)


class Alpha { Alpha doStuff(char c) { return new Alpha(); } } class Beta extends Alpha { Beta doStuff(char c) { // legal en Java 1.5 return new Beta(); } }

Valores de retorno (IV)


> En un mtodo que retorna un tipo primitivo, podemos retornar un valor o variable que pueda ser convertido implicitamente en el tipo de retorno declarado.
public int foo() { char c = 'c'; return c; // char es compatible con int }

Valores de retorno (V)


> En un mtodo que retorna un tipo primitivo, podemos retornar un valor o variable que pueda ser explicitamente convertidoen el tipo de retorno declarado.
public int foo() { float f = 32.5f; return (int)f; }

Pregunta
1. 2. 3. 4. 5. 6. class Programmer { Programmer debug() { return this; } } class SCJP extends Programmer { // insertar el cdigo aqu }

> Cual de estas lneas har que el programa compile? (pueden ser varias)
> A. Programmer debug() { return this; } > B. SCJP debug() { return this; } > C. Object debug() { return this; } > D. int debug() { return 1; } > E. int debug(int x) { return 1; } > F. Object debug(int x) { return this; }

Constructores e instanciacin
> Los constructores son el cdigo que se ejecuta siempre que utilizamos la palabra new. > No solo se ejecuta el constructor de la clase, sino tambin todos los constructores de las superclases. > Todas las clases, incluso las abstractas DEBEN tener un constructor.

Constructores
> Dos puntos clave a tener en cuenta acerca de los constructores es que no deben tener tipo de retorno y sus nombres deben ser exactamente los mismos que los de las clases a las que pertenecen. En general, se los utiliza para inicializar los estados de las variables de instancia:
class Foo{ int size; String name; Foo(String name, int size) { this.name = name; this.size = size; } }

Constructores (II)
>Caballo c = new Caballo();

> Qu sucede realmente ante esta llamada? (asumiendo que Caballo extiende Animal y Animal extiende Object).
1. 2. 3. 4. Main llama a new Caballo(). Caballo llama a super(). Animal llama a super(). Object().

Reglas para constructores


> Pueden usar cualquier modificador de acceso. > Es legal (aunque bastante estpido) tener un mtodo con el mismo nombre que la clase. > Si no creamos un constructor, el compilador agregar uno automticamente (sin argumentos)

Reglas para constructores (II)


>Si ya tenemos un constructor con argumentos, no se generar uno sin argumentos automticamente. >Cada constructor tiene, como primera sentencia, una llamada a un constructor sobrecargado (this) o a un constructor de la superclase (super), aunque esta lnea puede ser agregada automticamente por el compilador. >Los constructores no se heredan ni pueden sobrescribirse (no son mtodos)

Reglas para constructores (III)


>Si tu superclase no tiene un constructor sin argumentos, debers tipear un constructor en la subclase dado que necesitars un lugar desde donde llamar a super con los argumentos necesarios.
class Animal { Animal(String name) { } } class Horse extends Animal { Horse() { super(); // Problema } }

class Top { public Top(String s) { System.out.print("B"); } } public class Bottom2 extends Top { public Bottom2(String s) { System.out.print("D"); } public static void main(String [] args) { new Bottom2("C"); }} Cual es el resultado? A. BD B. DB C. BDC D. DBC E. Falla la compilacin.

? ?

Sobrecarga de constructores
> Los constructores se sobrecargan tpicamente para proveer formas alternativas de instanciar objetos de nuestra clase. > Una llamada a this() es retrasar lo inevitable, alguno de los constructores deber llamar a super(). > Regla clave: la primera lnea de un constructor debe ser una llamada a super() o una llamada a this().

public class Animal { String name; Animal(String name) { this.name = name; } Animal() { this(makeRandomName()); } static String makeRandomName() { int x = (int) (Math.random() * 5); String name = new String[] {"Fluffy","Fido","Rover", "Spike","Gigi"}[x]; return name; } }

class Uber { static int y = 2; Uber(int x) { this(); y = y * 2; } Uber() { y++; } } class Minor extends Uber { Minor() { super(y); y = y + 3; } public static void main(String [] args) { new Minor(); System.out.println(y); } }

> Cul es el resultado? A. 6 B. 7 C. 8 D. 9 E. Fallalacompilacin.

Pregunta
>Qu pasar si tratamos de compilar el siguiente cdigo? Dnde podra ir la llamada a super()? class A { A() { this("foo"); } A(String s) { this(); } }

? ?

Variables y mtodos estticos


> Supongamos que tenemos un mtodo en una clase utilitaria que siempre se ejecuta de la misma forma, en otras palabras, no depende del estado (valores de las variables de instancia) del objeto. > Las variables y mtodos marcadas como static, pertenecen a la clase, en vez de a una instancia particular. De hecho, pueden utilizarse sin tener ninguna instancia de la clase.

Static vs. no static


> Aquello no static, pertenecer al objeto, por lo que usaremos algo como:
class Foo{ Int x = 3; public static void main (String [] args) { Foo f = new Foo(); System.out.println("x is " + f.x); } }

Static vs. no static (II)


> Pero para aquello static usaremos algo como:
class Foo{ static int x = 3; public static void main (String [] args { System.out.println("x is " + Foo.x); System.out.println("x is " + x); } }

Conclusiones sobre Static


> Los mtodos estticos no pueden acceder a variables o mtodos no estticos. > Los mtodos estticos pueden acceder a mtodos y variables estticos. > Los mtodos estticos no pueden sobrescribirse. No quiere decir que no puedan ser redefinidos, pero redefinir y sobrescribir no son la misma cosa.

Sobrescribir vs. Ocultar


class Foo { public static void classMethod() { System.out.println("classMethod() in Foo"); } public void instanceMethod() { System.out.println("instanceMethod() in Foo"); } } class Bar extends Foo { public static void classMethod() { System.out.println("classMethod() in Bar"); } public void instanceMethod() { System.out.println("instanceMethod() in Bar"); }}

Sobrescribir vs. Ocultar (II)


class Test { public static void main(String[] args) { Foo f = new Bar(); f.instanceMethod(); f.classMethod(); } }

> Si ejecutamos esto, la salida ser:


instanceMethod() in Bar classMethod() in Foo

Preguntas

Potrebbero piacerti anche