Slides de la tercera clase del curso de Java SCJP dictado en la Universidad Nacional de Centro de La Provincia de Buenos Aires.
Contenido:
1. Ejemplos de Enum
2. Unidad 2: POO
Presentación guía sencilla en Microsoft Excel.pptx
SCJP, Clase 2: Ejemplos De Enum, Poo
1. SCJP 6
Clase 1.5 – Ejemplos de
enum
Ezequiel Aranda
Sun Microsystems Campus
Ambassador
2. 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/
3. Pre Java 5.0
> Antes de Java 5, la forma estándar de representar
una enumeración, era utilizar el pattern “int Enum”
public static final int SEASON_WINTER = 0;
public static final int SEASON_SPRING = 1;
public static final int SEASON_SUMMER = 2;
public static final int SEASON_FALL = 3;
> Este pattern tenía muchos problemas (no tenían
namespace, no eran typesafe, brittleness,
información nula al imprimirlos).
4. Java 5.0
> oporta enums como un tipo.
S
> on una clase.
S
> or lo tanto, pueden tener métodos y
P
variables, implementar interfaces, y más.
> roveen implementaciones de los métodos
P
heredados de Object.
> on Comparables y Serializables.
S
5. 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;
}
6. public Rank rank() { return rank; }
public Suit suit() { return suit; }
public String toString() { return rank + quot; dequot; +
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.
}
}
7. Ejemplo – Mazo de cartas (II)
> oString() de Card toma ventaja de toString
t
de Rank y Suit.
> l constructor de Card toma un Rank y un
E
Suit.
> alues() retorna un array que contiene los
v
elementos del enum.
8. 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;
}
}
9. Ejecución 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]
10. Agregar operaciones
public enum Planet {
MERCURY (3.303e+23, 2.4397e6),
VENUS (4.869e+24, 6.0518e6),
EARTH (5.976e+24, 6.37814e6),
MARS (6.421e+23, 3.3972e6),
JUPITER (1.9e+27, 7.1492e7),
SATURN (5.688e+26, 6.0268e7),
URANUS (8.686e+25, 2.5559e7),
NEPTUNE (1.024e+26, 2.4746e7),
PLUTO (1.27e+22, 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;
}
11. 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();
}
}
12. 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(quot;Your weight on %s is %f%nquot;,
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
14. AGENDA
> ncapsulamiento
E
> erencia (es un / tiene un)
H
> olimorfismo
P
> nterfaces
I
> alores de retorno legales
V
> onstructores
C
> étodos y variables estáticas
M
15. Encapsulamiento
> culta ciertos elementos de la
O
implementación de una clase proveyendo una
interfaz pública para los clientes.
> antiene las variables de instancia
M
protegidas (private).
> e utilizan métodos de accesos públicos,
S
forzando su utilización en vez de el acceso
directo a las variables de instancia
(set<Propiedad>, get<Propiedad>).
16. Encapsulamiento
ObjetoB.Metodo1()
Datos Datos
Objeto A Objeto B
Valor de retorno
17. Herencia
> l lenguaje Java permite que una clase herede
E
funcionalidad de una única clase.
> sto se conoce como “herencia simple”.
E
Scanner Impresora Deporte
✔
✖
Fotocopiadora Fútbol Rugby
18. Relaciones “es un”
> n POO, el concepto de “es un” se basa en la
E
herencia de clases o implementación de
interfaces. “Es un” es una forma de decir
“Esta cosa es un tipo de esa otra”.
Auto
Auto
Deportivo
19. Relaciones “Tiene un”
> stán basadas en el uso, más que en la
E
herencia. En otras palabras, la clase A tiene
un B si el código en la clase A tiene una
referencia a una instancia de la clase B.
> or ejemplo: un caballo ES UN animal y TIENE
P
UN cabestro. Escrito en Java, sería algo como:
public class Animal {}
public class Caballo extends Animal {
private Cabestro miCabestro;
}
20. Polimorfismo
> as invocaciones
L
polimorficas a métodos
sólo aplican a métodos
de instancia.
> iempre podremos referirnos a un objeto
S
con una variable de un tipo más general
(una superclase o interfaz).
> or lo tanto, podemos hacer cosas como:
P
Auto a = new AutoDeportivo();
21. 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 hiciéramos Employee e = new Manager(),
¿podríamos usar la variable department? ¿y que
resultado tendría la llamada a e.printDetail()?
22. Sobrescritura de métodos
> iempre que tengamos una clase que herede
S
un método de una superclase, tendremos la
posibilidad de sobrescribir dicho método.
> alvo que tal método sea final o static.
S
> l número y el tipo de los argumentos DEBEN
E
ser iguales.
23. Sobrescritura de métodos (II)
> l tipo a retornar debe ser el mismo (desde
E
Java 5.0, puede ser un subtipo del tipo
retornado por el método sobrescrito – tipos
covariantes).
> o puede ser menos accesible. Un
N
modificador más amplio sí es valido.
> o debe arrojar nuevas excepciones o
N
excepciones más amplias que las declaradas
por el método sobrescrito.
24. Invocar la versión presente en la
superclase de un método sobrescrito
public class Animal {
public void eat() { }
public void printYourself() {
// código de impresión
}
}
class Horse extends Animal {
public void printYourself() {
super.printYourself(); // Invocamos el código
//presente en Animal
// Luego agregamos código específico debajo
}
}
25. Sobrecarga de métodos
> La sobrecarga de
métodos permite reusar
el mismo nombre de un
método en una clase,
pero con una lista de
argumentos diferente.
> Un método sobrecargado DEBE cambiar la lista de
argumentos respecto del original.
> Un método sobrecargado PUEDE cambiar el tipo del
valor de retorno respecto del original.
26. Sobrecarga de métodos (II)
> n método sobrecargado PUEDE cambiar su
U
modificador de acceso respecto del original.
> n método sobrecargado PUEDE declarar
U
nuevas o más amplias excepciones que el
original.
> n método puede sobrecargarse en la misma
U
clase o en una subclase.
27. ¿Cual es el resultado de este código?
class Car { }
class BMW extends Car { }
class UsedCar{
public void doStuff(Car b) {
System.out.println(quot;In the Car versionquot;);
}
public void doStuff(BMW b) {
System.out.println(quot;In the BMW versionquot;);
}
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);
}
}
28. En resumen…
> a elección sobre que versión de un método
L
sobrescrito llamar, es hecha en tiempo de
ejecución, y se basa en el tipo del objeto.
> ientras que la elección sobre que versión de
M
un método sobrecargado llamar se basa en el
tipo de la referencia del argumento que se
pasa en tiempo de compilación.
29. Casting de variables de referencia
> acia abajo:
H
> anager m = (Manager) new Empleado();
M
> acia arriba:
H
> mpleado e = (Empleado) new Manager();
E
Empleado
Ingeniero Manager
30. Casting de variables de referencia (II)
> l compilador es forzado a confiar en nosotros
E
cuando hacemos un casting “hacia abajo”,
incluso cuando está mal.
> or lo que cuando hagamos algo como:
P
> anager m = (Manager) new Empleado();
M
El resultado será la aparición de una
excepción java.lang.ClassCastException en
tiempo de ejecución.
31. Implementando una interfaz
> l implementar una interfaz, estamos
A
aceptando adherirnos al contrato definido por
esa interfaz.
> mplica que deberemos proveer
I
implementaciones “legales” de todos los
métodos definidos en tal interfaz.
> as clases que implementan una interfaz
L
deben seguir las mismas reglas que las clases
que extienden clases abstractas.
32. Implementando una interfaz (II)
> roveer implementaciones no abstractas para
P
todos los métodos de la interfaz declarada.
> eguir todas las reglas para sobrescrituras.
S
> eclarar solo las mismas excepciones que
D
aquellas declaradas en el método de la
interfaz, o subclases de esas excepciones.
> antener la signatura y el tipo de retorno (o
M
un subtipo). No es necesario declarar las
excepciones.
33. Pregunta
Interface A {
void methodA();
}
public class Temp implements A{
void methodA() { }
}
??
> Compila? ¿Por qué?
¿
34. Implementando una interfaz (III)
> uando declaramos métodos en una interfaz,
C
el compilador los generará con los
modificadores public abstract.
> uando declaramos atributos en una interfaz,
C
el compilador los generará con los
modificadores static final.
35. Implementando una interfaz (IV)
> or lo tanto, podremos hacer cosas como:
P
> abstract class Ball implements Bounceable
> public class Ball implements Bounceable,
Serializable, Runnable
> public interface Bounceable extends
MoveRunnable
36. 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
37. 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 múltiples clases
> class Zoom implements Fi, Fee { } // OK. Una clase
puede extender múltiples interfaces
> interface Vroom extends Fi, Fee { } // OK. Una
interfaz puede extender múltiples interfaces
> class Yow extends Foo implements Fi { } // OK. Pero
extends debe ir primero
38. 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) { }
}
39. Valores de retorno
> n los métodos sobrecargados, no podemos
E
cambiar sólo el tipo de retorno.
public class Foo{
void go() { }
}
public class Bar extends Foo{
String go() { // No legal
return null;
}
}
40. Valores de retorno (II)
> étodos sobrescritos – A partir de Java
M
5, el tipo retornado en un método puede
ser un subtipo del tipo retornado en el
método (de la superclase) que este está
sobrescribiendo.
41. 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();
}
}
42. Valores de retorno (IV)
> n un método que retorna un tipo primitivo,
E
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
}
43. Valores de retorno (V)
> n un método que retorna un tipo primitivo,
E
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;
}
44. Pregunta
1. class Programmer {
2. Programmer debug() { return this; }
3. }
4. class SCJP extends Programmer {
5. // insertar el código aquí
6. }
> ¿Cual de estas líneas 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; }
45. Constructores e instanciación
> os constructores son el código que se
L
ejecuta siempre que utilizamos la
palabra “new”.
> o solo se ejecuta el constructor de la
N
clase, sino también todos los
constructores de las superclases.
> odas las clases, incluso las abstractas
T
DEBEN tener un constructor.
46. 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;
}
}
47. Constructores (II)
> Caballo c = new Caballo();
> Qué sucede realmente ante esta llamada?
¿
(asumiendo que Caballo extiende Animal y
Animal extiende Object).
1. Main llama a new Caballo().
2. Caballo llama a super().
3. Animal llama a super().
4. Object().
48. Reglas para constructores
> ueden usar cualquier modificador de
P
acceso.
> s legal (aunque bastante estúpido)
E
tener un método con el mismo nombre
que la clase.
> i no creamos un constructor, el
S
compilador agregará uno
automáticamente (sin argumentos)
49. Reglas para constructores (II)
> Si ya tenemos un constructor con argumentos, no se
generará uno sin argumentos automáticamente.
> Cada constructor tiene, como primera sentencia,
una llamada a un constructor sobrecargado (this) o
a un constructor de la superclase (super), aunque
esta línea puede ser agregada automáticamente por
el compilador.
> Los constructores no se heredan ni pueden
sobrescribirse (no son métodos)
50. Reglas para constructores (III)
> Si tu superclase no tiene un constructor sin
argumentos, deberás tipear un constructor en la
subclase dado que necesitarás un lugar desde donde
llamar a super con los argumentos necesarios.
class Animal {
Animal(String name) { }
}
class Horse extends Animal {
Horse() {
super(); // Problema
}
}
51. class Top {
public Top(String s) {
System.out.print(quot;Bquot;);
}
}
public class Bottom2 extends Top {
public Bottom2(String s) {
System.out.print(quot;Dquot;);
}
public static void main(String [] args) {
new Bottom2(quot;Cquot;);
??
}}
¿Cual es el resultado?
A. BD
B. DB
C. BDC
D. DBC
E. Falla la compilación.
52. Sobrecarga de constructores
> os constructores se sobrecargan típicamente
L
para proveer formas alternativas de instanciar
objetos de nuestra clase.
> na llamada a this() es retrasar lo inevitable,
U
alguno de los constructores deberá llamar a
super().
> egla clave: la primera línea de un
R
constructor debe ser una llamada a super() o
una llamada a this().
53. 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[]
{quot;Fluffyquot;,quot;Fidoquot;,quot;Roverquot;, quot;Spikequot;,quot;Gigiquot;}[x];
return name;
}
}
54. class Uber {
> Cuál es el resultado?
¿
static int y = 2;
Uber(int x) {
A. 6
this();
y = y * 2;
B. 7
}
Uber() { y++; }
C. 8
}
D. 9
class Minor extends Uber {
Minor() {
E. Falla la compilación.
super(y);
y = y + 3;
}
public static void main(String [] args) {
new Minor();
System.out.println(y);
}
}
55. Pregunta
> ¿Qué pasará si tratamos de compilar el siguiente
código? ¿Dónde podría ir la llamada a super()?
class A {
A() {
this(quot;fooquot;);
??
}
A(String s) {
this();
}
}
56. Variables y métodos estáticos
> upongamos que tenemos un método en una
S
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.
> as variables y métodos marcadas como
L
static, pertenecen a la clase, en vez de a una
instancia particular. De hecho, pueden
utilizarse sin tener ninguna instancia de la
clase.
57. Static vs. no static
> quello “no static”, pertenecerá al objeto,
A
por lo que usaremos algo como:
class Foo{
Int x = 3;
public static void main (String [] args) {
Foo f = new Foo();
System.out.println(quot;x is quot; + f.x);
}
}
58. Static vs. no static (II)
> ero para aquello static usaremos algo como:
P
class Foo{
static int x = 3;
public static void main (String [] args {
System.out.println(quot;x is quot; + Foo.x);
System.out.println(quot;x is quot; + x);
}
}
59. Conclusiones sobre Static
> os métodos estáticos no pueden acceder a
L
variables o métodos no estáticos.
> os métodos estáticos pueden acceder a
L
métodos y variables estáticos.
> os métodos estáticos no pueden
L
sobrescribirse. No quiere decir que no puedan
ser redefinidos, pero redefinir y sobrescribir
no son la misma cosa.
60. Sobrescribir vs. Ocultar
class Foo {
public static void classMethod() {
System.out.println(quot;classMethod() in Fooquot;);
}
public void instanceMethod() {
System.out.println(quot;instanceMethod() in Fooquot;);
}
}
class Bar extends Foo {
public static void classMethod() {
System.out.println(quot;classMethod() in Barquot;);
}
public void instanceMethod() {
System.out.println(quot;instanceMethod() in Barquot;);
}}
61. Sobrescribir vs. Ocultar (II)
class Test {
public static void main(String[] args) {
Foo f = new Bar();
f.instanceMethod();
f.classMethod();
}
}
> i ejecutamos esto, la salida será:
S
instanceMethod() in Bar
classMethod() in Foo