Indice Introducción a Java (II). Indice 2 Índice Introspección Introducción a las relaciones...

37
Indice Introducción a Java (II)

Transcript of Indice Introducción a Java (II). Indice 2 Índice Introspección Introducción a las relaciones...

Page 1: Indice Introducción a Java (II). Indice 2 Índice Introspección Introducción a las relaciones Herencia Agregación.

Indice

Introducción a Java (II)

Page 2: Indice Introducción a Java (II). Indice 2 Índice Introspección Introducción a las relaciones Herencia Agregación.

Indice 2

Índice

• Introspección• Introducción a las relaciones• Herencia• Agregación

Page 3: Indice Introducción a Java (II). Indice 2 Índice Introspección Introducción a las relaciones Herencia Agregación.

Indice

Introspección

Page 4: Indice Introducción a Java (II). Indice 2 Índice Introspección Introducción a las relaciones Herencia Agregación.

Indice

Introducción• Java tiene interesantes mecanismos para obtener

información interna de las clases, es decir, los objetos Java pueden informarnos de su propia estructura. Por ello se llaman utilidades de introspección

• Vamos a centrarnos en lo fundamental de la introspección: un objeto o una clase puede informarnos de la clase a la que pertenece

• La clase más importante es java.lang.Class. Es una clase que nos permite describir cualquier clase Java. Dicho de otra forma, es un descriptor o referencia de una clase.

• Un paquete relevante es java.lang.reflect

4

Page 5: Indice Introducción a Java (II). Indice 2 Índice Introspección Introducción a las relaciones Herencia Agregación.

Indice

Conocer el tipo• En tiempo de ejecución puede saber el tipo (clase) que

manejamos:– Si tenemos un objeto, puedo conocer su clase:

Coche miCoche = new Coche();Class clase = miCoche.getClass();System.out.println("Clase:" +clase.getName() );

Lo que hemos hecho es obtener un descriptor de clase (tipo Class) mediante miCoche.getClass(). Este descriptor nos devuelve su nombre mediante getName()

– Si tenemos una clase (no hay instancias):Coche.class.getName()

– getName() nos devuelve el nombre de la clase, incluyendo la jerarquía de paquetes. En nuestro ejemplo:

newInstance.dominio.Coche

5

Page 6: Indice Introducción a Java (II). Indice 2 Índice Introspección Introducción a las relaciones Herencia Agregación.

Indice

newInstance()• Podemos cargar de manera dinámica un objeto, es decir, determinar en tiempo de ejecución (y no en tiempo

de programación) la clase que vamos a instanciar• Primero haremos una pequeña clase (Coche) de prueba:

package newInstance.dominio;public class Coche extends Vehiculo {

private int plazas = 5;

public Coche() {}public Coche( int plazas ) { this.plazas = plazas; }public int getPlazas() { return plazas; }public void setPlazas( int p ) { plazas = p; }public String toString() {

try { return super.toString() + " Plazas:" + String.valueOf(plazas); }catch (Exception e) { return "-1"; }

}}

• A continuación crearemos un objeto del tipo Class, que es un descriptor de la estructura de datos o clase. Lo conseguimos con forName(). El paso siguiente es crear una instancia de la clase con newInstance().

Class clase = Class.forName( “newInstance.dominio.Coche” );Object objeto = clase.newInstance();System.out.println(“Coche:" + objeto.toString() );

• Necesitamos al menos un constructor sin parámetros (Coche()) para el uso de newInstance() o bien no especificar ninguno. Pero, si se especifica uno que tenga parámetros (Coche( int plazas )), entonces debe también implementar uno sin parámetros, ya que este es el que usa newInstance()

• Hemos determinado la clase desde una cadena en el código (newInstance.dominio.Coche). Esto no es muy dinámico. Pero las posibilidades de carga dinámica son evidentes:

– Un ejemplo puede ser que en función de una acción del usuario podemos instanciar una clase u otra. En un archivo properties podemos tener la asociación de acciones y clases.

– Otro ejemplo: puedo cargar todas las clases que haya en un determinado directorio, sin tener que determinar estáticamente (a priori en el código) las clase que cargo.

6

Page 7: Indice Introducción a Java (II). Indice 2 Índice Introspección Introducción a las relaciones Herencia Agregación.

Indice

Introducción a las relaciones

Page 8: Indice Introducción a Java (II). Indice 2 Índice Introspección Introducción a las relaciones Herencia Agregación.

Indice

Introducción (I)

• Estamos acostumbrados a ver que diferentes tipos de objetos (naturales o artificiales) se relacionan, por ejemplo en una fabrica, universidad o un despacho de abogados

• Con las clases ocurre algo parecido, se relacionan entre si. Los dos tipos fundamentales de relaciones son:– Relación de clasificación o herencia (jerarquía de

tipos).– Relación de agregación (jerarquía de partes)

8

Page 9: Indice Introducción a Java (II). Indice 2 Índice Introspección Introducción a las relaciones Herencia Agregación.

Indice

Introducción (II)La relación de clasificación o herencia es bastante común. Un autobús o un camión son tipos de vehículo, del mismo modo que un ingeniero o un contable son tipos de empleados. Las subclases (como el autobús o el camión) tienen atributos comunes, por el hecho de ser tipos de la clase vehículo. También decimos que heredan atributos de su superclase:

9

Vehículo

marcamodeloprecio...

Camión

cargaMax

Autobús

plazasAdemás heredan Marca,

Modelo y precio

Lo que no significa que toda clasificación sea sensata. Borges habla de una enciclopedia china donde “está escrito que los animales se dividen en: a) pertenecientes al emperador b) embalsamados c) amaestrados d) lechones e) sirenas f) fabulosos g) perros sueltos h) incluídos en esta clasificación i) que se agitan como locos j) innumerables k) dibujados con un pincel finísimo de pelo de camello l) etcétera. m) que acaban de romper el jarrón n) que de lejos parecen moscas“ (“El idioma analítico de John Wilkins”, Otras inquisiciones, Emecé Editores, Buenos Aires, 1960, p. 142)

Page 10: Indice Introducción a Java (II). Indice 2 Índice Introspección Introducción a las relaciones Herencia Agregación.

Indice

Introducción (III)• La relación de agregación es también bastante frecuente. Por ejemplo,

cuando decimos que: – Una empresa se compone de una serie de departamentos– El catálogo comercial se compone de una serie de productos– La carta de un restaurante se compone de una serie de platos y bebidas

• Tipos:– Composición. La parte (departamento) desaparece cuando desaparece el todo

(Empresa). Otro ejemplo: casa/cocina.– Contenedor. El componente (Ratón) no desaparece con el contenedor

(Computadora). Otro ejemplo: cesta/manzanas.

10

Catálogo Producto

Empresa Departamento

Page 11: Indice Introducción a Java (II). Indice 2 Índice Introspección Introducción a las relaciones Herencia Agregación.

Indice

Herencia

La relación en la que una clase base es el supertipo o generalización de una subclase o subtipo (como la clase

base Persona y la subclase Librero). Entender los mecanismos de la herencia implica comprender el

polimorfismo

Page 12: Indice Introducción a Java (II). Indice 2 Índice Introspección Introducción a las relaciones Herencia Agregación.

Indice

Un primer ejemplo de herencia• Empezamos representando la relación de herencia entre vehículo y

autobus, para una agencia de alquiler:

12

public class Vehiculo {

public int precioDia = 36;

public String marcaModelo = "Volvo" ;

public Vehiculo() {

System.out.println( "Construyo un vehículo");

}

public void mostrarCaracteristicas() {

System.out.print( "Marca: " + marcaModelo +

“ Precio: " + precioDia);

}

}

public class Autobus extends Vehiculo {

public int plazas = 55;

public Autobus() {

System.out.println( "Ha creado un autobus" );

}

public void mostrarCaracteristicas() {

System.out.print( "Marca: " + marcaModelo +

“ Precio: " + precioDia);

System.out.println( " Plazas: " + plazas );

}

} public static void main(String[] args) {

Autobus v1 = new Autobus();

v1.mostrarCaracteristicas();

}

Construyo un vehículo

Ha creado un autobus

Marca: Volvo Precio: 36 Plazas: 55

Es un primer ejemplo en el que el objeto v1 (clase “Autobus”) hereda los atributos de la clase “Vehículo” (usa la palabra extends):

marcaModelo precioDia

Page 13: Indice Introducción a Java (II). Indice 2 Índice Introspección Introducción a las relaciones Herencia Agregación.

Indice

Algunas críticas• El ejemplo anterior mostraba la herencia de

atributos, pero tenía varios inconvenientes, entre los que destaca:– No aprovecha la herencia de métodos– Los atributos no son parametrizados (¿sólo hay

Volvos?)– Repetimos la sentencia System.out.print( "Marca: " + marcaModelo + "Precio:

" + precioDia); en la clase hija– Los datos no son protegidos o encapsulados (principio

de ocultamiento de información)• En resumen, podemos hacerlo mejor

13

Page 14: Indice Introducción a Java (II). Indice 2 Índice Introspección Introducción a las relaciones Herencia Agregación.

Indice

Mejorando el ejemplo

14

public class Vehiculo {

protected int precioDia;

protected String marcaModelo ;

public Vehiculo( String marcaModelo, int precioDia ) {

defMarcaModelo( marcaModelo );

defPrecioDia( precioDia );

System.out.println( "Construyo un vehículo");

}

public void mostrarCaracteristicas() {

System.out.print( "Marca: " + marcaModelo +

“ Precio: " + precioDia);

}

public void defPrecioDia( int precioDia ) {

this.precioDia = precioDia;

}

...

}

public class Autobus extends Vehiculo {

private int plazas = 55;

public Autobus( String marcaModelo, int precioDia,

int plazas) {

super( marcaModelo, precioDia );

this.plazas = plazas;

System.out.println( "Ha creado un autobus" );

}

public Autobus( String marcaModelo, int precioDia ) {

super( marcaModelo, precioDia );

System.out.println( "Ha creado un autobus" );

}

void mostrarCaracteristicas() {

super.mostrarCaracteristicas();

System.out.println( " Plazas: " + plazas );

}

}

DESDE MAIN():

Autobus v1 = new Autobus( "Volvo 550", 120, 57);

v1.mostrarCaracteristicas();

v1.defPrecioDia( 130 );

v1.mostrarCaracteristicas();

Construyo un vehículo

Ha creado un autobus

Marca: Volvo 550 Precio: 120 Plazas: 57

Marca: Volvo 550 Precio: 130 Plazas: 57

Page 15: Indice Introducción a Java (II). Indice 2 Índice Introspección Introducción a las relaciones Herencia Agregación.

Indice

Notas al ejemplo• En Vehiculo:

– Los atributos son protected: esto significa que serán privados para las clases hijas

• En Autobus:– Usamos extends para indicar que es una clase hija de Vehiculo– El atributo plazas tiene un valor por defecto de 55, que sería el que tomase con el

segundo constructor. Observar que el segundo constructor no recibe valor para esta variable, por tanto, su valor sería el de la inicialización (el 55)

– El uso de super() nos permite enviar valores al constructor de la clase madre– El método mostrarCaracteristicas() sobreescribe o anula el método idéntico de la clase

madre. Para acceder al método anulado usa super.:super.mostrarCaracteristicas();

De esta forma el interprete Java sabe que queremos ejecutar la versión de mostrarCaracteristicas() que está en la clase madre

• En main:– Observar la herencia de métodos: el objeto de la clase Autobus llama a defPrecioDia(),

método heredado de la clase Vehiculo

15

Page 16: Indice Introducción a Java (II). Indice 2 Índice Introspección Introducción a las relaciones Herencia Agregación.

Indice

Los usos de la palabra super• En la forma de llamada a una función significa

una llamada al constructor de la clase madre. Debe colocarse en la primera línea del constructor de la hija:

Autobus( String marcaModelo, int precioDia, int plazas) { super( marcaModelo, precioDia ); this.plazas = plazas; System.out.println( "Ha creado un autobus" );}

• En la forma de referencia a un objeto (super.) significa que llamamos a un método de la clase madre que ha sido sobreescrito:

void mostrarCaracteristicas() { super.mostrarCaracteristicas(); System.out.println( " Plazas: " + plazas ); }

16

Page 17: Indice Introducción a Java (II). Indice 2 Índice Introspección Introducción a las relaciones Herencia Agregación.

Indice

Modificadores de acceso y herencia

17

Page 18: Indice Introducción a Java (II). Indice 2 Índice Introspección Introducción a las relaciones Herencia Agregación.

Indice

Herencia de datos privados (private)• Si algo es private en la clase madre: NO SE PUEDE ACCEDER

DESDE LA SUBCLASE (NO SE HEREDA). Pero si se puede acceder desde la subclase a un método de la clase madre que usa ese dato. Por ejemplo, si hago que el precio sea privado:

public class Vehiculo {  private int precioDia;    ....

}

• Entonces puedo mostrar por pantalla el precio PORQUE LO MUESTRA UN METODO HEREDADO DE LA SUPERCLASE, getPrecioDia() :

public class j08_agencia_alquiler {  public static void main(String[] args) {    Autobus v = new Autobus( "XXX 800", 140, 58);    System.out.println( v.getPrecioDia() );

  }}

• v.getPrecioDia() es un método heredado de la clase madre y es este método el responsable de mostrar el precio por pantalla. Pero desde la clase Autobus (subclase) no puedo usar precioDia, tampoco desde la clase j08_agencia_alquiler, que esta en el mismo paquete

18

Page 19: Indice Introducción a Java (II). Indice 2 Índice Introspección Introducción a las relaciones Herencia Agregación.

Indice

Herencia de datos protected (protegidos)• Si algo es protected en la clase base: SE PUEDE ACCEDER

DESDE LA SUBCLASE Y LAS CLASES DEL MISMO PAQUETE (aunque no sean subclases). Ejemplo siguiendo lo anterior: si ponemos:

public class Vehiculo {  protected int precioDia;    ....

}

• Las siguientes líneas en main() serían correctas:public class j08_agencia_alquiler {

  public static void main(String[] args) {    Autobus v = new Autobus( "XXX 800", 140, 58);    System.out.println( v.getPrecioDia() );    System.out.println( v.precioDia );                    // NO ES UN ERROR

  }}

• Puede observarse que el atributo precioDia es accesible para la clase j08_agencia_alquiler (donde está main()), PORQUE ESTA EN EL MISMO PAQUETE.

19

Page 20: Indice Introducción a Java (II). Indice 2 Índice Introspección Introducción a las relaciones Herencia Agregación.

Indice

Herencia de datos public (públicos)• Accesible para cualquier subclase o clase

(dentro o fuera del paquete).

 

• POR DEFECTO: Si no pongo modificador, los atributos y métodos son:– Públicos para las clases del mismo paquete o

subclases– Privados para las clases de otros paquetes o

subclases

20

Page 21: Indice Introducción a Java (II). Indice 2 Índice Introspección Introducción a las relaciones Herencia Agregación.

Indice

Herencia de datos: un consejo

• A modo de resumen y consejo general:

– Si queremos que algo se herede y se pueda usar desde otro paquete, usar public

– Si queremos que algo se herede y no se pueda usar desde otro paquete (pero si desde el propio paquete), usar protected

– Si no se quiere heredar ni acceder, private.

21

Page 22: Indice Introducción a Java (II). Indice 2 Índice Introspección Introducción a las relaciones Herencia Agregación.

Indice

Otro ejemplo de sobreescritura de métodosLas clases hijas (Rectangulo y Circulo) sobreescriben el método getArea():

22

public class Figura {

protected Punto posicion;

public void setPosicion(Punto posicion) {

this.posicion = posicion;

}

public Punto getPosicion() { return posicion; }

public double getArea() { return 0; }

}

public class Circulo extends Figura {

private double radio;

static final public double PI = 3.1416;

public double getArea() {

return radio * radio * PI;

}

}

public class Rectangulo extends Figura {

private double ancho;

private double largo;

public double getArea() {

return ancho * largo;

}

}

Cada subtipo de “figura” tiene un método getArea(), pero cada método implementa a su manera el cálculo del área. Por ello se dice que nos encontramos ante polimorfismo: un interfaz y múltiples implementaciones.

Un interfaz ya que el interfaz (la declaración del método) es idéntico.

Múltiples implementaciones: hay múltiples formas de calcular el área.

Page 23: Indice Introducción a Java (II). Indice 2 Índice Introspección Introducción a las relaciones Herencia Agregación.

Indice

Polimorfismo• La sobreescritura de métodos permite el polimorfismo. La clase madre

especifica un método, que las clases derivadas sobreescriben, de tal forma que cada clase derivada tiene su implementación del método

• Por ello, se habla de polimorfismo: un interfaz (la misma declaración de método) y múltiples implementaciones (múltiples formas de calcular el área)

• Veamos el siguiente ejemplo. Tenemos una referencia (f) de la clase madre Figura ¿cómo sabe el programa el método getArea() que debe ejecutar?, en función del objeto que se crea (en este caso un círculo):

public static void main(String[] args) { Figura f; f = new Circulo( 40, 40, 3 ); System.out.println( f.getArea() ); f = new Rectangulo( 12, 10, new Punto(30, 33) ); System.out.println( f.getArea() ); }

23

Page 24: Indice Introducción a Java (II). Indice 2 Índice Introspección Introducción a las relaciones Herencia Agregación.

Indice

Clases abstractas• En nuestro ejemplo de figuras la clase madre no tiene implementación del método

getArea()• Esto no es raro en una clase madre, en muchas ocasiones las clases más elevadas en una

jerarquía de herencia especifican un interfaz (declaración de función), sin definir una implementación. En nuestro ejemplo no se puede calcular el área de una figura (si de un Rectángulo o un Círculo)

• Denominamos clases abstractas a aquellas que tienen o heredan un método abstracto, es decir, métodos declarados pero no implementados.

• No puede haber instancias de las clases abstractas, lo que no resulta extraño: nos puede interesar que se hagan instancias de Rectangulo o Circulo, pero no permitir instancias de Figura.

• En nuestro ejemplo la clase madre puede ser:package figuras.dominio;abstract public class Figura { protected Punto posicion;

public void setPosicion(Punto posicion) { this.posicion = posicion; } public Punto getPosicion() { return posicion; } abstract public double getArea();}

24

Las clases hijas deben implementar el método abstracto

Page 25: Indice Introducción a Java (II). Indice 2 Índice Introspección Introducción a las relaciones Herencia Agregación.

Indice

final

• La palabra final tiene varios sentidos:– Precediendo a una variable: la define como una

constante y no puede ser modificada– Precediendo a un método: indica que el método

no puede ser sobrescrito– Precediendo a una clase: indica que no se pueden

definir subclases

25

Page 26: Indice Introducción a Java (II). Indice 2 Índice Introspección Introducción a las relaciones Herencia Agregación.

Indice

Agregación

Una relación en la que el objeto es una parte de otro objeto (como la batería es

una parte del teléfono móvil). Nos ayudaremos de la clase Vector del JDK

Page 27: Indice Introducción a Java (II). Indice 2 Índice Introspección Introducción a las relaciones Herencia Agregación.

Indice

Agregación: composición• En ocasiones interesa crear objetos que se

componen de otros objetos• La parte desaparece cuando desaparece el todo

27

public class Casa {

private Dormitorio dormitorios[];

private Salon salon;

private Cocina cocina;

}

Page 28: Indice Introducción a Java (II). Indice 2 Índice Introspección Introducción a las relaciones Herencia Agregación.

Indice

Agregación: contenedor

• El componente (por ejemplo, un producto de un catálogo comercial) no desaparece con el contenedor (catálogo)

• Conviene usar alguna de las clases del JDK para hacer colecciones de objetos, por ejemplo Vector, ArrayList, etc.

• Están en el paquete java.util

28

Page 29: Indice Introducción a Java (II). Indice 2 Índice Introspección Introducción a las relaciones Herencia Agregación.

Indice

Vector (I)• En Java las matrices son de longitud fija, una vez creadas no se puede

modificar su tamaño• Hay un truco para saltarse esta limitación: crear otra matriz más grande y

copiar de la matriz original a la nueva• Java nos suministra una clase, denominada Vector, que nos permite utilizar

una matriz de longitud variable• Constructores:

– Vector(): tamaño inicial de 100 y se incrementa duplicando tamaño– Vector( int tamaño ): señala el tamaño y se incrementa duplicando tamaño– Vector( int tamaño, int incremento ): señala tamaño e incremento

• Para añadir: add( Object elemento ). Ejemplo:Vector v = new Vector(50,5);v.add( new Persona( “Pedro” ) );

• En muchos métodos se tiene en cuenta el índice o posición dentro del Vector. Por ello, conviene recordar que el primer elemento es el cero. Para insertar en una posición determinada (desplazando el resto hacia la derecha): insertElementAt( Object elemento, int posición )

29

Page 30: Indice Introducción a Java (II). Indice 2 Índice Introspección Introducción a las relaciones Herencia Agregación.

Indice

Vector (II)• Para conocer el número de elementos, así como la

capacidad del Vector tenemos int size() e int capacity():

Vector v = new Vector(50,5);v.addElement( new Persona( “Pedro” ) );System.out.println( v.size() ); // Muestra 1System.out.println( v.capacity() ); // Muestra 50

• Para eliminar un elemento: removeElementAt( int posición ). Desplaza los elementos de la derecha para llenar el hueco.

• Para obtener el elemento de la posición indicada: Object elementAt( int posición ) u Object get( int posición )

30

Page 31: Indice Introducción a Java (II). Indice 2 Índice Introspección Introducción a las relaciones Herencia Agregación.

Indice

Versión “final” del proyecto de las figuras

• Vamos a ver como queda finalmente el proyecto de las figuras, en el que se ha aplicado:

– Modularización: se ha separado en tres paquetes la presentación, clases del dominio y la clase de inicio

– Encapsulamiento: datos privados. Tambien la complejidad de la presentación queda encapsulada (oculta), al final no hay más que llamar al método “VistaFiguras.mostrar()”, pasando como argumento el objeto que se quiere mostrar

– Sobrecarga de métodos– Herencia: hay una clase madre “Figura” que tiene métodos y atributo para la posición

de la figura– Clase abstracta: la clase “Figura” es además abstracta, ya que tiene el método abstracto

“getArea()”– Agregación: la clase Pagina es un contenedor de figuras– Una clase (Figura) usa de otra (Punto). El atributo “Punto posicion” de la clase Figura

hace referencia al punto de su posición– Atributo static y final: “Circulo.PI”, ya que sólo hay un número PI, aunque haya cero o

millones de círculos– Métodos static: “VistaFigura.mostrar()”, no hace falta instanciar la clase para llamar al

método. Es una forma de implementación común en clases de utilidad.

31

Page 32: Indice Introducción a Java (II). Indice 2 Índice Introspección Introducción a las relaciones Herencia Agregación.

Indice

Versión “final” del proyecto de las figuras. Los puntos y las figuras

package figuras.dominio;

public class Punto { private int x; private int y;

public Punto(int x, int y) { setPunto(x, y); } public Punto(Punto p) { setPunto(p ); } public void setPunto(int x, int y) { this.x = x; this.y = y; } public void setPunto(Punto p) { x = p.getX(); y = p.getY(); }

public int getX() { return x; } public int getY() { return y; }

public String toString() { return "(" + x + "," + y + ")"; }}

32

Todas las figuras usan de Punto, ya que todas heredan el atributo 'posicion' de Figura

Figura es una clase abstracta

package figuras.dominio;

abstract public class Figura { protected Punto posicion;

public void setPosicion(Punto posicion) { this.posicion = posicion; } public Punto getPosicion() { return posicion; } abstract public double getArea();}

Page 33: Indice Introducción a Java (II). Indice 2 Índice Introspección Introducción a las relaciones Herencia Agregación.

Indice

Versión “final” del proyecto de las figuras. Los círculospackage figuras.dominio;

public class Circulo extends Figura { private double radio; static final public double PI = 3.1416;

public Circulo() { } public Circulo( double nuevoRadio, Punto nuevaPosicion ) { setRadio( nuevoRadio ); setPosicion( nuevaPosicion ); } public Circulo( double nuevoRadio, int posicionX, int posicionY ) { setRadio( nuevoRadio ); posicion = new Punto( posicionX, posicionY ); } public Circulo( Circulo circulo ) { setRadio( circulo.getRadio() ); setPosicion( circulo.getPosicion()); } public void setRadio( double radio ) { this.radio = radio; } public double getRadio() { return radio; } public double getArea() { return radio * radio * PI; } public String toString() { return "Radio: " + radio + " Posicion: " + posicion.toString() + " Area: " +

getArea(); }}

33

Los círculos heredan de Figura, por tanto tienen que implementar el método getArea()

Page 34: Indice Introducción a Java (II). Indice 2 Índice Introspección Introducción a las relaciones Herencia Agregación.

Indice

Versión “final” del proyecto de las figuras. Los rectángulospackage figuras.dominio;

public class Rectangulo extends Figura { private double ancho; private double largo;

public Rectangulo( double ancho, double largo, Punto posicion ) { setDimensiones( ancho, largo ); setPosicion(posicion); } public void setDimensiones( double ancho, double largo ) { this.ancho = ancho; this.largo = largo; } public double getArea() { return ancho * largo; }

public String toString() { return "Ancho: " + ancho + " Largo: " + largo + " Posicion: " + posicion.toString() " Superficie: " + getArea(); }}

34

Page 35: Indice Introducción a Java (II). Indice 2 Índice Introspección Introducción a las relaciones Herencia Agregación.

Indice

Versión “final” del proyecto de las figuras. La página (agregador)package figuras.dominio;

import java.util.*;

public class Pagina { private Vector vecFiguras = new Vector(); public void agregar( Figura fig ) {

vecFiguras.add( fig ); } public boolean desagregar( int indice ) { if ( indice < vecFiguras.size() ) { try { vecFiguras.remove(indice); return true; } catch (Exception e) { return false; } } return false; } public Figura obtener( int indice ) { if ( indice < vecFiguras.size() ) { try { return (Figura) vecFiguras.get(indice); } catch (Exception e) { return null; } } return null; } public int tamanio() { return vecFiguras.size(); }} 35

• Utilizamos la clase java.util.Vector para agregar figuras

• La utilidad de usar la herencia (o los interface lógicos): en “agregar()” usamos una referencia genérica (Figura fig). Este método puede recibir cualquier clase hija (Rectangulo, Circulo, etc.). Es muy interesante ya que, si no fuese así, tendríamos que implementar el método agregar para cada una de las subclases

• En “obtener()” no eliminamos o quitamos el objeto del vector, simplemente devolvemos una referencia al objeto. ¿Por qué necesitamos hacer casting?

• Gestionamos excepciones con try - catch

Page 36: Indice Introducción a Java (II). Indice 2 Índice Introspección Introducción a las relaciones Herencia Agregación.

Indice

Versión “final” del proyecto de las figuras. La visualizaciónpackage figuras.presentacion;

import figuras.dominio.*;

public class VistaFiguras {

public static void mostrar( Circulo cir ) { if ( cir != null ) System.out.println( cir.toString() ); else System.out.println( "Error al intentar mostrar el círculo" );

}

public static void mostrar( Rectangulo rec ) { if ( rec != null ) System.out.println( rec.toString() ); else System.out.println( "Error al intentar mostrar el rectángulo" ); }

public static void mostrar( Pagina pag ) { if ( pag == null ) { System.out.println("Error al intentar mostrar la página"); return; } for ( int i = 0; i < pag.tamanio(); i++ ) { Figura fig = pag.obtener(i); System.out.println( fig.toString() ); } }}

36

Aspectos a resaltar:

• Polimorfismo con sobrecarga de métodos: todos los métodos se llaman igual, pero actúan de forma diferente (patrón estrategia)

• Para mostrar las figuras de una página: recorremos los elementos con un for(). Dentro del for(), para obtener la figura (sea un rectángulo o un círculo) usamos una referencia genérica del tipo “Figura” (clase madre), a la que mandamos el mensaje toString(). Un ejemplo típico de polimorfismo: usamos el mismo mensaje (toString) para producir comportamiento diferente, en función del objeto unos se representan de una forma y otros de otra

Page 37: Indice Introducción a Java (II). Indice 2 Índice Introspección Introducción a las relaciones Herencia Agregación.

Indice

Versión “final” del proyecto de las figuras. El inicioimport figuras.presentacion.*;

class Inicio { //// Usa agregador public static void main(String[] args) { Circulo primero = new Circulo( 23, 2, 3 ); Circulo copia = new Circulo( primero ); Circulo tercero = new Circulo( 17, new Punto(8,9) ); Rectangulo rectangulo = new Rectangulo(3.5, 2, new Punto(55,54)); Pagina pag = new Pagina(); pag.agregar( primero); pag.agregar( copia); pag.agregar( tercero ); pag.agregar( rectangulo );

VistaFiguras.mostrar( pag ); }}

37

Puesto que el método mostrar() es static podemos usar VistaFiguras sin

instanciarla