Download polimorfismo.

Document related concepts
no text concepts found
Transcript
Curso
Programación en Java
Tema 6
Herencia y Polimorfismo
Ignacio Zahonero Martínez
Luis Joyanes Aguilar
GENERALIZACIÓN/ESPECIALIZACIÓN

Una generalización se conoce como una relación es-un, es-un-tipo-de. Es una relación entre clases
especializadas de una clase general. Un Vendedor es-un Empleado, una Opera es-un Espectáculo, un Rectángulo
es un tipo de Forma.

La generalización es una relación entre una clase general y una clase específica. La clase específica, denominada
subclase, hereda de la clase general. Se heredan los atributos y las operaciones.

La clase general agrupa los atributos y los métodos comunes a las clases especializadas.

La generalización se representa con una línea de la clase más específica a la clase más general con un triángulo
vacío en el extremo de la línea de la superclase.

Una subclase o clase hija puede ser a su vez clase base de otra lo que produce jerarquías de clases.

En las jerarquías de generalización/especialización, hacia arriba se generaliza. La clase más alta en la jerarquía
es la clase más general. la clase base.

La implementación de la generalización en un lenguaje de programación se conoce como herencia.
Ignacio Zahonero Martínez
Luis Joyanes Aguilar
2
JERARQUÍAS DE GENERALIZACÍON
Cuenta
Cuenta
Cuenta
corriente
vivienda
Cuenta
de valores
Registro
Registro
Registro
de pasajero
de vuelo
vuelo
compartido
Ignacio Zahonero Martínez
Luis Joyanes Aguilar
vuelo
operacional
pasajero
turista
pasajero
de empresa
3
CONCEPTOS ESENCIALES

La creación de una clase a partir de una existente se denomina derivación.

A la capacidad de definir una clase a partir de otra clase ya existente y de añadirle comportamiento y estado se
conoce como extensión de la clase original (Java).

El comportamiento de una clase se puede extender mediante un mecanismo que recibe el nombre de herencia.
class BilleteElectronico extends Billete
{

La clase BilleteElectonico extiende de Billete. Por consiguiente, BilleteElectronico es una subclase de
Billete y Billete es la superclase (clase base) de BilleteElectronico.

Al crear un objeto de tipo BilleteElectronico se crea un único objeto que consta del objeto de tipo Billete
extendido con los atributos propios de BilleteElectronico. Todos los métodos (no privados) de Billete y de
BilleteElectronico se pueden invocar directamente desde el objeto BilleteElectronico.
BilleteElectronico e = new BilleteElectronico("Ignacio", 233, "Madrid", visa);

Todo objeto de la clase BilleteElectronico es-un objeto de tipo Billete.
Ignacio Zahonero Martínez
Luis Joyanes Aguilar
4
HERENCIA

Mediante la propiedad de herencia se permite a los objetos ser construidos a partir de otros
objetos. Por ejemplo, un objeto ventana de texto se construye a partir del objeto ventana.

Otra forma de expresar la propiedad de herencia, la capacidad de un objeto para utilizar las
estructuras de datos y los métodos de objetos ascendientes o antepasados.

El objetivo final es la reutilización, es decir, reutilizar el código anteriormente desarrollado.

La herencia implica una clase base y una jerarquía de clases que contienen las clases derivadas de
la clase base. Las clases derivadas heredan el código de su clase base, añadiendo su propio código
especial, incluso cambian aquellos elementos de la clase base que necesita sean diferentes.

La herencia se apoya en el significado de ese concepto en la vida ordinaria. La clases básicas se
dividen en subclases. La clase Electrodoméstico se divide en subclase Lavadora, Cocina,
Lavavajillas, etc. La jerarquía comparte características comunes; si bien una lavadora tiene
características especiales que la diferencian de una cocina.

Las características y comportamiento comunes se definen en la clase base.
Ignacio Zahonero Martínez
Luis Joyanes Aguilar
5
TIPOS DE HERENCIA

Hay dos de tipos de herencia: herencia simple y herencia múltiple.

La herencia simple es aquella en la que cada clase hereda de una única clase.

La herencia múltiple es la transmisión de métodos y datos de más de una clase base a la clase derivada.

Por ejemplo, en el contexto de una simulación la clase Concurre ( representa actividades concurrentes ) puede
tener dos clase base, la clase Tarea y la clase Dato.

Dos problemas se pueden presentar cuando se diseñan clases con herencia múltiple:
• Colisiones de nombres de diferentes clases base.
• Herencia repetida de una misma clase base.

Las jerarquías de herencia múltiple pueden ser complejas de gestionar. De hecho, no todos los
lenguajes OO la implementan.

Java, C# y Smalltalk no implementa la herencia múltiple. Eiffel y C++ admiten herencia simple y
múltiple.
Ignacio Zahonero Martínez
Luis Joyanes Aguilar
6
HERENCIA MÚLTIPLE
Motor
- potencia
MotorGas
MotorElectrico
- tiempoExplos
- intensidad
MotorHíbrido
 Esta jerarquía con herencia múltiple presenta el problema de repetición del atributo potencia en la clase
MotorHibrido.
Ignacio Zahonero Martínez
Luis Joyanes Aguilar
7
HERENCIA SIMPLE
Artículo
Audio
Vídeo
Radio
Altavoz
Amplificador
CD
 En esta jerarquía cada clase tiene como máximo una sola superclase. La herencia simple permite que una
clase herede las propiedades de su superclase jerárquica.
Ignacio Zahonero Martínez
Luis Joyanes Aguilar
8
IMPLEMENTACIÓN DE HERENCIA
 En Java la herencia se conoce como derivación o extensión. Se emplea la palabra reservada
extends.
 Sintaxis :
class Base { ... }
class Derivada extends Base
{
// atributos nuevos de Derivada
// métodos nuevos de Derivada
}
 Los miembros privados de la clase base nunca son visibles en la clase derivada.
 En la clase derivada se pueden invocar a las versiones originales de los métodos redefinidos
utilizando super.
 En general, super hace referencia a la porción del objeto Padre que tiene el objeto Hijo.
Ignacio Zahonero Martínez
Luis Joyanes Aguilar
9
REGLAS DE ACCESO A LA CLASE BASE

Los miembros públicos de la clase base son también miembros públicos de la clase derivada, los miembros
protegidos de la clase base se convierten en protegidos de la clase derivada, y los miembros privados de la clase
base no son visibles en la clase derivada.
class Cartilla
{
private String tit;
protected double saldo;
public void ingresar(double q)
{
saldo += q;
}
class Ahorrro extends Cartilla
{
private int duracion;
public void informe()
{
if (saldo > 0 ...// heredado
System.out.println(tit);
}
Ignacio Zahonero Martínez
Luis Joyanes Aguilar
// error, no visible
10
CONSTRUCTOR DE UN OBJETO DERIVADO
 La información para construir una parte del objeto derivado reside en la clase base. Por esa razón
antes de aplicar el constructor de la clase derivada se aplica el constructor de la clase base. Por
ejemplo, al crear un objeto Profesional primero se crea la parte de Persona y, a continuación la
parte de Profesional.
 Si la clase base fuese, a su vez, derivada de otra clase base, antes de crearse la porción del objeto
correspondiente a esta se crearía la parte de su clase base. Y así sucesivamente.
 El constructor de una clase debe inicializar sólo los datos que dicha clase añada a la jerarquía.
 La inicialización de los datos de la clase base se realiza llamando explícitamente al constructor de la
clase base.
 En Java, la llamada al constructor de la clase base desde el constructor de la clase derivada se
realiza con super() proporcionando los argumentos requeridos por dicho constructor.
Ignacio Zahonero Martínez
Luis Joyanes Aguilar
11
OBJETO DERIVADO
public class Lampara
{
private int pot;
protected String desr;
public Lampara(int pot, String d)
{
this.pot = pot;
desr = d;
}
// ...
public class LamparaGas extends Lampara
{
private double cd;
public LamparaGas(int pt, String ds, double can)
{
super (pt, ds);
cd = can;
}
Ignacio Zahonero Martínez
Luis Joyanes Aguilar
12
SUSTITUCIÓN/REDEFINICIÓN

Los atributos y métodos definidos en la superclase se heredan por las subclases. Si la propiedad se define
nuevamente en la subclase, entonces esta definición es la utilizada en la subclase.

La capacidad de una clase derivada (subclase) para definir un miembro con el mismo nombre que un miembro
heredado se denomina redefinición (anulación o sustitución son términos equivalentes).
class Telef {
public void sonar() {
System.out.print(" rin rin ");
}
class Movil extends Telef{
public void sonar() {
cancion.audio();
}
class Fijo extends Telef {
public void sonar() {
System.out.
print(" ron ron ");
}

Cuando se referencia al miembro redefinido desde un objeto de la subclase, se usará el miembro definido por
dicha subclase.

El miembro heredado de la superclase no se pierde por ser redefinido, es posible acceder a dicho miembro
cualificándolo (en Java con super).

La clase Fijo puede redefinir sonar(), añadiendo a las características de sonar() de Telef las propias de Fijo:
public void sonar() {
super.sonar();
System.out.print(" ron ron ")
}
Ignacio Zahonero Martínez
Luis Joyanes Aguilar
13
CLASES ABSTRACTAS(I)

Las clases abstractas definen un concepto o tipo generalizado y sirven para describir nuevas clases. Una clase
abstracta no se puede instanciar y sólo tiene significado como clase base de otras clases.

En las jerarquías de clases, las superclases que se crean a partir de subclases con atributos y comportamientos
comunes, y que sirven para derivar otras clases que comparten sus características, son clases abstractas.
Ignacio Zahonero Martínez
Luis Joyanes Aguilar
14
CLASES ABSTRACTAS(II)
 Las clases abstractas representan conceptos generales, engloban las características comunes de un
conjunto de objetos. Persona, en un contexto de trabajadores, es una clase abstracta que engloba las
propiedades y métodos comunes a todo tipo de persona que trabaja para una empresa.
 En Java el modificador abstract declara a una clase abstracta:
abstract class NombreClase { // ... }
Por ejemplo,
public abstract class Persona
{
private String apellido;
public void identificacion(String a, String c){ ...}
public abstract void darAlta();
}
 Las clases abstractas declaran métodos y variables instancia, y normalmente tienen métodos abstractos.
Una clase que tiene un método abstracto debe declararse abstracta.
 Los métodos abstractos no pueden ser static.
Ignacio Zahonero Martínez
Luis Joyanes Aguilar
15
CLASES ABSTRACTAS(III)
Normas de las clases abstractas.
• Una clase abstracta se declara con la palabra reservada abstract como prefijo en la cabecera de la
clase.
• Una clase con al menos un mètodo abstracto es una clase abstracta y hay que declararla como
abstracta.
• Una clase derivada que no redefine un método abstracto es también clase abstracta.
• Las clases abstractas pueden tener variables instancia y métodos no abstractos.
• No se pueden crear objetos de clases abstractas.
Ignacio Zahonero Martínez
Luis Joyanes Aguilar
16
CLASES ABSTRACTAS(IV)
Ejemplo: Se define un array de la clase abstracta Figura y se crean objetos de las clase
concretas Rectangulo y Circulo.
public abstract class Figura { public abstract double area(); ... }
public class Circulo extends Figura { ...}
Figura []af = new Figura[10];
for (int i = 0; i < 10; i++)
{
if (i %2 ==0)
af[i] = new Rectangulo(2,7);
else
af[i] = new Circulo(3.5);
}
Ignacio Zahonero Martínez
Luis Joyanes Aguilar
17
POLIMORFISMO
Ignacio Zahonero Martínez
Luis Joyanes Aguilar
18
POLIMORFISMO
 El polimorfismo permite referirse a objetos de diferentes clases por medio del mismo elemento y
realizar la misma operación de formas diferentes, de acuerdo al objeto a que se hace referencia en
cada momento.

Otra forma de definir el polimorfismo: el envío del mismo mensaje desencadena acciones diferentes
según el objeto que lo recibe. Un ejemplo típico es la operación arrancar cuando se aplica a diferentes
tipos de motores; en cada caso la operación de arrancar se realiza de forma diferente.
 La construcción del lenguaje que hace posible el polimorfismo es la ligadura dinámica (conocida
también por ligadura tardía o postergada) entre llamadas a métodos y los cuerpos reales de dichos
métodos.
 La ligadura dinámica supone que el código a ejecutar en respuesta a un mensaje no se determinará
hasta el momento de ejecución.
 En Java la ligadura dinámica se basa en la capacidad de redefinir (reemplazar) métodos en la
subclase, en el contexto de herencia.
Ignacio Zahonero Martínez
Luis Joyanes Aguilar
19
POLIMORFISMO
 Conclusión:
En una jerarquía de herencia, cuando se llama a métodos desde una referencia a la superclase que han sido
redefinidos en las clases derivadas, lo que se tiene en cuenta es el tipo del objeto actual referenciado. De tal forma
que se ejecutará el método redefinido en el tipo actual.
En definitiva, al llamar a un mismo método sobre una misma variable referencia se producirá la llamada a métodos
distintos dependiendo del objeto referenciado.

En una jerarquía de Vehículos que deben pagar el peaje de una autopista:
Vehiculo cual;
// public abstract class Vehiculo { ... }
cual = new Turismo();
cual.calculoTasa();
cual = new CicloMotor();
cual.calculoTasa();
cual = new Camion();
cual.calculoTasa();

La llamada es sobre una variable de tipo Vehiculo, el método ejecutado depende del objeto actual referenciado.
Ante un mismo mensaje se responde de formas diferente  POLIMORFISMO.
Ignacio Zahonero Martínez
Luis Joyanes Aguilar
20
USO DEL POLIMORFISMO
 El polimorfismo se puede representar con un array de elementos que se
refieren a objetos de diferentes tipos (clases), como sugiere Meyer .

Para poder utilizar polimorfismo en Java se deben seguir las siguientes reglas:
1. Crear una jerarquía de clases con las operaciones importantes definidas por las métodos miembro declaradas
como abstractos en la clase base.
2. Las implementaciones específicas de los métodos abstractos se deben hacer en las clases derivadas. Cada clase
derivada puede tener su propia versión del método.
3. Las instancias de estas clases se manejan a través de una referencia a la clase base
 Realmente no es necesario declarar los métodos en la clase base abstrasctos, si después
se redefinen (misma signatura) en la clase derivada.
Ignacio Zahonero Martínez
Luis Joyanes Aguilar
21
EJEMPLO DE POLIMORFISMO(1)
 Consideremos la clase Instrumento como la clase base de la que se derivan otras clases, tales como Piano, Guitarra,
GitarraEléctrica y Bombo. Cada instrumento musical debe tener la posibilidad de tocar una pieza y afinar. En este caso la
clase Instrumento declara los siguientes métodos:
class Instrumento
{
public void tocar(String cd)
{
System.out.println("instrumento interpreta " + cd);
}
// public abstract bool afinar();
// NO SE DESARROLLA
}
Cada clase derivada debe definir sus propias versiones concretas de los métodos que han sido declarados en la clase base.
class Piano extends Instrumento
{
public void tocar(String cd)
{
System.out.println(
"Piano interpreta "+ cd);
}
}
Ignacio Zahonero Martínez
Luis Joyanes Aguilar
class Guitarra extends Instrumento
{
public void tocar(String cd)
{
System.out.println(
"Guitarra " + cd);
}
}
22
EJEMPLO DE POLIMORFISMO(2)
class Bombo extends Instrumento
{
public void tocar(string cd)
{
System.out.println(
"Bombo toca " + cd); };
}
class GuitarraElectrica extends Guitarra
{
public void tocar(String cd)
{
System.out.println(
"Guitarra electrica toca " + cd);
}
}
 Por ejemplo, las siguientes llamadas:
Bombo b1;
Guitarra g1;
Instrumento it;
b1.tocar("Panocha");
g1.tocar("Aranjuez");
it.tocar("Piano");
son llamadas directas, y se enlazan a un código específico en la compilación ( ligadura estática).
Ignacio Zahonero Martínez
Luis Joyanes Aguilar
23
EJEMPLO DE POLIMORFISMO(3)
 Ahora se va a llamar al método redefinido tocar() a través de una referencia a la superclase Instrumento.
Instrumento pin[]= new Instrumento[5];
pin[0] = new GuitaraElectica();
pin[1] = new Instrumento();
pin[2] = new Guitara();
pin[3] = new Bombo();
pin[4] = new Piano();
for (int i = 0; i < pin.length; i++)
pin[i].tocar("Rumba");
 En la llamada pin[i].tocar("Rumba") se produce ligadura dinámica; el compilador no puede determinar cuál es la
implementación específica del método tocar() que se ha de ejecutar. La salida que genera la ejecución:
Guitarra electrica toca Rumba
instrumento interpreta Rumba
Guitarra interpreta Rumba
Bombo toca Rumba
Piano interpreta Rumba
 El polimorfismo es una característica de los lenguajes O.O que consiste en que el método exacto que se llama queda
determinado en el momento de ejecución por la clase del objeto receptor.
Ignacio Zahonero Martínez
Luis Joyanes Aguilar
24
EJEMPLO: CLASES BEBIDA
Ignacio Zahonero Martínez
Luis Joyanes Aguilar
En el modelado de clases de una aplicación sobre tipos de bebidas se tiene las clases:
Bebida.
Atributos: precio, clave identificación
métodos: constructor sin args., constructor con precio, constructor con clave y
constructor con clave y precio. Redefinición de de toString() y finalize(). Además de
métodos set y get
Café. Amplia la clase Bebida.
Atributos: descripción y país de origen.
métodos: constructor sin args., constructor para inicializar objetos con precio y país.
Redefinición de de toString() y finalize(). Además de métodos set y get
Te. Amplia la clase Bebida.
Atributos: minutos de reposo, tipo (negro, verde, rojo: Te.NEGRO = 1.
Te.VERDE = 2, Te.ROJO = 3).
métodos: constructor sin args., constructor para inicializar objetos con tipo y clave.
Redefinición de de toString() y finalize().Además de métodos set y get
Principal:
crear un array de bebidas
crear objetos Cafe/Te y guardarlos en el array
recorrer el array de bebidas, mostrar las características de cada bebida y el precio.
Repetir la creación de objetos pero guardarlos en un Vector.
Ignacio Zahonero Martínez
Luis Joyanes Aguilar
26
Clase abstracta Bebida. Archivo Bebida.java (I)
package Bebidas;
public abstract class Bebida
{
protected double precio;
protected String idt;
/** Constructores */
public Bebida() throws BebidaException
{
this(0.0, "b000-00");
}
public Bebida(double p, String id) throws BebidaException
{
if (p <= 0.0) throw new BebidaException("Datos de Bebida no correctos: " + p);
precio = p;
idt = id;
}
public Bebida(double p) throws BebidaException
{
this(p, "b000-00");
}
Ignacio Zahonero Martínez
Luis Joyanes Aguilar
27
Clase abstracta Bebida. Archivo Bebida.java (II)
public Bebida(String id) throws BebidaException
{
this(0.0, id);
}
/** métodos de acceso */
public void set(double p)throws BebidaException
{
if (p <= 0.0) throw new BebidaException("Datos de Bebida no correctos: " + p);
precio = p;
}
public void set(String id)
{
idt = id;
}
public double getPrecio()
{
return precio;
}
Ignacio Zahonero Martínez
Luis Joyanes Aguilar
28
Clase abstracta Bebida. Archivo Bebida.java (III)
public String getIdt()
{
return idt;
}
/** redefinición de métodos */
public String toString()
{
return "Precio: " + precio + ", " + " Identificación:" + idt;
}
protected void finalize()
{
System.out.println("Bebida " + toString() + " liberada");
}
}
Ignacio Zahonero Martínez
Luis Joyanes Aguilar
29
Clase Café, deriva de Bebida. Archivo Cafe.java (I)
package Bebidas;
public class Cafe extends Bebida
{
private String descripcion = "NO INFO ";
private String pais;
/** Creates a new instance of Cafe */
public Cafe() throws BebidaException
{
this(1,"Brasil");
}
public Cafe (double precio, String pais)throws BebidaException
{
super(precio);
this.pais = pais;
}
/** métodos de acceso a miembros */
public void setPais(String p)
{
pais = p;
}
Ignacio Zahonero Martínez
Luis Joyanes Aguilar
30
Clase Café, deriva de Bebida. Archivo Cafe.java (II)
public void setDescripcion(String d)
{
descripcion = d;
}
public String getDescripcion()
{
return descripcion;
}
/** redefinición de métodos */
public String toString()
{
return "CAFE: "+ super.toString() +
". Pais: " + pais+ ", " + "\nCaracteristicas:" + descripcion;
}
protected void finalize()
{
super.finalize();
System.out.println("Cafe" + getDescripcion() + " liberada");
}
}
Ignacio Zahonero Martínez
Luis Joyanes Aguilar
31
Clase Te, deriva de Bebida. Archivo Te.java (I)
package Bebidas;
public class Te extends Bebida
{
private int minutos;
public enum Tipo {NEGRO, VERDE, ROJO;}
Tipo tipo;
public Te() throws BebidaException
{
this( "NEGRO", "00-1t");
}
public Te(String tipo, String clave) throws BebidaException
{
super(0.5, clave);
this.tipo = Enum.valueOf(Tipo.class, tipo); // método static de clase java.lang.Enum,
// devuelve la constante enumerada
}
Ignacio Zahonero Martínez
Luis Joyanes Aguilar
32
Clase Te, deriva de Bebida. Archivo Te.java (II)
/** métodos de acceso a miembros */
public void setTiempo(int t)
{
minutos = t;
}
public void setTipo(String tipo)
{
this.tipo = Enum.valueOf(Tipo.class, tipo);
}
public int getTiempo()
{
return minutos;
}
public String getTipo()
{
return tipo.toString(); // cadena con la cte enumerada actual
}
Ignacio Zahonero Martínez
Luis Joyanes Aguilar
33
Clase Te, deriva de Bebida. Archivo Te.java (III)
/** redefinición de métodos */
public String toString()
{
return "TE: " + super.toString() +
". TE " + getTipo()+ ", " + "\nTiempo de reposo:" + minutos;
}
protected void finalize()
{
super.finalize();
System.out.println("TE " + getTipo() + " liberada");
}
Ignacio Zahonero Martínez
Luis Joyanes Aguilar
34
Clase BebidaException, para control de errores. Archivo BebidaException.java
package Bebidas;
public class BebidaException extends Exception
{
/** Creates a new instance of BebidaException */
public BebidaException() {
}
public BebidaException(String m)
{
super(m);
}
public String getMessage()
{
return "Excepción comprobada: "+ super.getMessage();
}
}
Ignacio Zahonero Martínez
Luis Joyanes Aguilar
35
Aplicación, en el método main() de la clase de prueba, se crean objetos de tipo Café o
Te, se guardan en un array y, en paralelo, en un contenedor de tipo ArrayList. Una vez
que se da entrada a los objetos, se recorre el array de tal forma que cada elemento se
pone en println(), automáticamente se llama al método toString() de cada tipo de
Bebida. En un caso se llama a toString() de Café, y en otro caso a toString() de
Te, dependiendo del objeto al que en ese momento referencia Bebida; es una llamada
polimórfica. También se recorre el contenedor ArrayList con un iterador, se diseña el
típico while.
La clase "importa" el paquete Bebidas para utilizar sus clases.
Archivo PruebaBebida.java (I)
import Bebidas.*;
import java.util.*;
public class PruebaBebida
{
static final int MX = 11;
public PruebaBebida() {
}
Ignacio Zahonero Martínez
Luis Joyanes Aguilar
36
Archivo PruebaBebida.java (II)
public static void main(String[]a)
{
Bebida[] b;
ArrayList <Bebida> ab;
Scanner entrada = new Scanner(System.in);
String idt;
double precio;
int i, op;
i = 0;
b = new Bebida[MX];
ab = new ArrayList<Bebida>();
do {
System.out.
println("Menú para elegir un tipo de
bebida. 1 -> Café, 2 -> Te, 3 -> Salir");
do
op = entrada.nextInt();
while (op < 1 || op >3) ;
Ignacio Zahonero Martínez
Luis Joyanes Aguilar
37
Archivo PruebaBebida.java (III)
try {
switch (op) {
case 1 : String cp, ds;
System.out.println("Bebida elegida café; teclea precio y código");
precio = entrada.nextDouble();
idt = entrada.next();
System.out.println("Pais de origen");
cp = entrada.next();
System.out.println("Descripción");
ds = entrada.next();
Cafe cf;
cf = new Cafe(precio, cp); // inicializa al precio y pais de origen
cf.setDescripcion(ds);
cf.set(idt);
// identificación
// asigna el objeto
if (i < b.length)
b[i++] = cf;
ab.add(cf);
break;
Ignacio Zahonero Martínez
Luis Joyanes Aguilar
38
Archivo PruebaBebida.java (IV)
case 2 : String t;
int mn;
System.out.println("Bebida elegida TE; teclea precio y código");
precio = entrada.nextDouble();
idt = entrada.next();
System.out.println("Tipo de Te (NEGRO, VERDE, ROJO)");
t = entrada.next().toUpperCase();
System.out.println("minutos de preparación");
mn = entrada.nextInt();
Te te;
te = new Te(); // constructor por defecto
te.setTipo(t);
te.setTiempo(mn);
te.set(idt);
// identificación
te.set(precio);
// asigna el objeto
if (i < b.length)
b[i++] = te;
ab.add(te);
break;
Ignacio Zahonero Martínez
Luis Joyanes Aguilar
39
Archivo PruebaBebida.java (V)
case 3 :
System.out.println("Finaliza la entrada, "+i+" objetos leídos ");
}
}
// cierre de la región controlada (bloque try)
catch (BebidaException e)
{
System.out.println(e.getMessage());
}
catch (Exception e)
{
System.out.println("Error global " + e);
}
finally {
System.out.println("Bloque finally");
entrada.nextLine();
}
} while (op != 3);
Ignacio Zahonero Martínez
Luis Joyanes Aguilar
// bucle de entrada
40
Archivo PruebaBebida.java (VI)
// se recorren los contenedores
System.out.println("Recorre el array con un bucle ");
for (int j = 0; j < i; j++)
System.out.println(b[j].toString()); // no es necesario llamar a toString()
// se recorren el contenedor ArraList
Iterator <Bebida> it;
it = ab.iterator();
// inicializa
System.out.println("Itera por el contenedor ");
while (it.hasNext())
{
System.out.println(it.next());
it.remove(); // como ejemplo, no es necesario
}
System.out.println("Recorre el array con un bucle para liberar objetos ");
for (int j = 0; j < i; j++)
b[j] = null;
System.gc();
}
// cierra bloque de método main()
} // fin de clase
Ignacio Zahonero Martínez
Luis Joyanes Aguilar
41
Propuesta:
Añadir a la estructura la clase Manzanilla con estas características:
Manzanilla. Amplia la clase Bebida.
Atributos: composición-propiedades (cadena); esEngrano, esInfusion
métodos: constructor sin args., constructor para inicializar objetos con precio,
identificación y composición- propiedades. Métodos set/get.
Redefinición de toString() y finalize().
Clase principal: modificar el menú con el fin de que también pueda crear objetos de tipo
Manzanilla.
Ignacio Zahonero Martínez
Luis Joyanes Aguilar
42
INTERFACES
Ignacio Zahonero Martínez
Luis Joyanes Aguilar
43
INTERFACE(I)
 Java incorpora una construcción del lenguaje, llamada interface, que permite declarar un
conjunto de constantes y de cabeceras de métodos abstractos. Es como una clase abstracta pura.
 En cierto modo, es una forma de declarar que todos los métodos de una clase son públicos y
abstractos, con ello se especifica el comportamiento común de todas las clases que implementen
el interfaz.
 Puede contener atributos, pero siempre serán estáticos y constantes de forma implícita.
 La declaración de un interface es similar a la de una clase; en la cabecera se utiliza la palabra
reservada interface en vez de class, por ejemplo:
public interface NodoG
{
boolean igual(NodoG t);
NodoG asignar(NodoG t);
void escribir(NodoG t);
}
Ignacio Zahonero Martínez
Luis Joyanes Aguilar
44
INTERFACE(II)
 Sintaxis:
acceso interface NombreInterface
{
constante1;
...
constanten;
tipo1 nombreMetodo1(argumentos);
...
tipon nombreMetodon (argumentos);
}
acceso visibilidad del interfaz definido, normalmente public
 Un interface es un tipo de referencia, por lo que se puede utilizar como argumento
de un método, o como variable. Por ejemplo:
NodoG g = new NodoPila();//class NodoPila implements NodoG{...}
Ignacio Zahonero Martínez
Luis Joyanes Aguilar
45
IMPLEMENTACIÓN DE UN INTERFACE
 El interface especifica el comportamiento común que tiene un conjunto de clases.
Dicho comportamiento se implementa en cada una de las clases. Para lo cual se utiliza
una sintaxis similar a la derivación o extensión de una clase, con la palabra reservada
implements en lugar de extends.
 Sintáxis:
class NombreClase implements NombreInterfaz
{
//
//
//
definición de atributos
implementación de métodos de la clase
implementación de métodos de interface
 La clase que implementa un interfaz tiene que especificar el código (la
implementación) de cada uno de sus métodos . De no hacerlo la clase se convierte en
clase abstracta y entonces debe de declararse abstract, es una forma de obligar a
que cada método del interfaz se implemente.
Ignacio Zahonero Martínez
Luis Joyanes Aguilar
46
EJEMPLO DE INTERFACE (I)
 Considerese una jerarquía de barcos, todos tienen como comportamiento común
msgeSocorro() y alarma(). Las clases BarcoPasaje, PortaAvion y Pesquero
implementan el comportamiento común.
 Interface Barco:
public interface Barco
{
void alarma();
void msgeSocorro(String av);
}
Ignacio Zahonero Martínez
Luis Joyanes Aguilar
47
EJEMPLO DE INTERFACE (II)
 Clase BarcoPasaje :
public class BarcoPasaje implements Barco
{
private int eslora;
private int numeroCamas = 101;
public BarcoPasaje()
{
System.out.println("Se crea objeto BarcoPasaje.");
}
public void alarma()
{
System.out.println("¡¡¡ Alarma del barco pasajero !!!");
}
public void msgeSocorro(String av)
{
alarma();
System.out.println("¡¡¡ SOS SOS !!!" + av);
}
}
Ignacio Zahonero Martínez
Luis Joyanes Aguilar
48
EJEMPLO DE INTERFACE (III)
 Clase PortaAvion :
public class PortaAvion implements Barco
{
private int aviones = 19;
private int tripulacion;
public PortaAvion(int marinos)
{
tripulacion = marinos;
System.out.println("Se crea objeto PortaAviones.");
}
public void alarma()
{
System.out.println("¡¡¡ marineros a sus puestos !!!");
}
public void msgeSocorro(String av)
{
System.out.println("¡¡¡ SOS SOS !!! " + av);
}
}
Ignacio Zahonero Martínez
Luis Joyanes Aguilar
49
EJEMPLO DE INTERFACE (IV)
 Clase Pesquero :
class Pesquero implements Barco
{
private int eslora;
private double potencia;
private int pescadores;
String nombre;
public Pesquero(int tripulacion)
{
pescadores = tripulacion;
System.out.println("Se crea objeto Barco Pesquero.");
}
public void alarma()
{
System.out.println("¡¡¡ Alarma desde el pesquero " +
nombre + " !!!");
}
public void msgeSocorro(String av)
{
System.out.println("¡¡¡ SOS SOS !!!, " + av);
}
}
Ignacio Zahonero Martínez
Luis Joyanes Aguilar
50
EJEMPLO DE INTERFACE (V)
 Escribir una aplicación en la que se creen objetos de tipo BarcoPasaje, PortaAvion y
Pesquero de forma arbitraria (según elija el usuario) guarden en un array o vector.
Una vez que se tenga la estructura con los objetos, recorrer(iterar) la estructura de tal
forma que cada objeto envíe los mensajes alarma() y socorro().
Ignacio Zahonero Martínez
Luis Joyanes Aguilar
51
MÚLTIPLES INTERFACE ,s
 Una clase puede implementar más de un interface, puede tener el comportamiento
común de varios interface. Sencillamente, a continuación de la palabra reservada
implements se escriben los interface separados por comas. La clase tiene que
implementar los métodos de todos los interfaces.
Sintaxis:
public class NombreClase implements Interfaz1, Interfaz2,…,Interfazn
{
// …
}
 Una clase puede heredar de su clase base y a la vez implementar un interface
public interface Parque {…}
public class EspacioProtegido {…}
public class ZonaAve extends EspacioProtegido {…}
public class ZonaAve extends EspacioProtegido
implements Parque, Componente{…}
Ignacio Zahonero Martínez
Luis Joyanes Aguilar
52
VARIABLES INTERFACE
 Se pueden declarar variables de tipo interface; cualquier variable de una clase que implementa
a un interface se puede asignar a una variable del tipo del interface.
Ejemplo:
interface Bolsa
{
Bolsa insertar (Object elemento);
}
public class Bolsa1 implements Bolsa
{
public Bolsa insertar(Object e)
{ ... }
}
public class Bolsa2 implements Bolsa
{
public Bolsa insertar(Object e)
{ ... }
}
Ignacio Zahonero Martínez
Luis Joyanes Aguilar
Bolsa q;
q = new Bolsa1();
q.insertar("Manzana");
...
q = new Bolsa2();
q.insertar(Integer(5));
53
EJERCICIOS (I)
1.
Una empresa fabrica tres tipos distintos de aleaciones metálicas. La composición porcentual de cada aleación es el siguiente:
Hierro
Cobre
Zinc
aleación A
0.7
0.2
0.1
aleación B
0.3
0.7
-
aleación C
0.4
-
0.6
El precio por tonelada de cada aleación viene dado por el precio de los materiales más el coste del proceso de fabricación: El precio
por Tm de los materiales es, Hierro: 3211, Cobre: 2705, Zinc: 3050.
Por otra parte el coste de los procesos de fabricación depende del peso de la aleación y es:
coste de aleación A (p) = 200*p2 + 125*p
coste de aleación B (p) = Ln (p) * p + 25*p
coste de aleación C (p) = 2025*p
Se pide:
a) Diseñar una jerarquía de clases.
b) Declarar y definir cada clase de la jerarquía.
c) Escribir un programa que permita introducir un número n de pedidos y los guarde cada pedido en un array. Una vez realizados los
pedidos se ha de recorrer el array para escribir en pantalla la característica de cada pedido, calcular su presupuesto y el total.
Ignacio Zahonero Martínez
Luis Joyanes Aguilar
54
EJERCICIOS(II)
2.
Supongamos un sucursal bancaria que maneja diferentes tipos de cuentas. Toda cuenta contiene 3 atributos comunes: año de
apertura, nombre del propietario y saldo.
Existen cuatro tipos de cuentas: Vivienda, Valores, Corriente y Ahorro. Cada una de las cuales tiene atributos adicionales:
Vivienda: precio de la vivienda y tipo.
Valores: nombre del valor y dinero invertido (por simplicidad, suponer un único valor)
Corriente: fecha del último movimiento(dia, mes y año) y cantidad.
Ahorro: Interes de la cuenta (tanto por cien).
a) Diseñar una jerarquía de clases.
b) Encontrar operaciones que puedan definirse polimórficamente.
c) Declarar y definir cada clase de la jerarquía.
d) Escribir un programa que guarde una lista de cuentas bancarias con datos leídos del teclado. A continuación realizar operaciones
con las cuentas, como, por ejemplo, ingresar dinero, dar intereses... .
3.
Implementar una jerarquía empleado de cualquier tipo de empresa que le resulte conocida. La jerarquía debe tener al menos 3
niveles, con herencia de miembros. La operaciones deben poder calcular salarios, dar de alta, generar primas. Estas operaciones se
realizarán de acuerdo al tipo de empleado. Escribir un programa que cree objetos de los diferentes tipos de empleados y realice
operaciones polimórficas.
4.
Escribir una clase Figura que represente figuras geométricas talec como triángulo, triángulo equilatero, cuadrado, rectángulo y cículo.
Debe proporcionar métodos que permitan dibujar, calcular el area, calcular el pérímetro y destruir tales objetos. Escribir un programa
que cree objetos de las figuras concretas, los guarde en un array o lista y realice operaciones polimórficas (cáculo del área ... ).
Ignacio Zahonero Martínez
Luis Joyanes Aguilar
55
EJERCICIOS(III)
5.
Un huerto está especializado en tres tipos de productos: Leguminosas, Tubérculos y Flores. Cada producto tiene su nombre, fecha de
siembra y fecha de recogida.
Además, de las Leguminosas interesa saber el tiempo de secado que necesitan, un vez recolectadas.
De los Tubérculos, la producción por metro cuadrado. Y la variedad del tubérculo (cadena).
De las Flores, los litros de agua que consumen por día y metro cuadrado, desde la siembra al día de recogida.
Cada tipo de producto se representa con una clase, del mismo nombre. Además, la clase Producto es la clase base de la jerarquía de
productos.
El constructor de la clase Producto tiene un argumento String con el nombre, y la fecha de siembra. Con los métodos set se podrán
cambiar o asignar.
El constructor de la clase Leguminosa pondrá el nombre, la fecha de siembra y el tiempo estimado de secado (posteriormente puede
cambiar).
El constructor deTubérculo pondrá el nombre y la variedad. Con un método set se informará de la producción.
El constructor de la clase Flores pondrá el nombre, la fecha de siembra y una estimación de la fecha de recogida. Con un método set
se pondrá el agua diaria consumida.
Cada una de las clases debe redefinir el método String toString().
Escribir una aplicación (clase principal) en la que se creen objetos de los diferentes productos, se guarden en una colección. Una vez
creada la colección, recorrer los elementos y mostrar sus características.
Ignacio Zahonero Martínez
Luis Joyanes Aguilar
56
EJERCICIOS(IV)
6.
Suponer que el Huerto del ejercicio 5 está dirigido por un ingeniero agrícola y colaboran N personas. Del ingeniero es necesario saber:
nombre y dirección; Sueldo asignado;Hora de entrada al trabajo y de salida diaria.
De los colaboradores se quiere guardar:
nombre y dirección; Sueldo por hora trabajada; Horas que trabaja cada día y el Producto (Legun¡minosa, Tubérculo o Flores) que tiene asignado
La aplicación debe ser capaz de:
a)
b)
c)
d)
Conocer para cada tipo producto el personal colaborador asignado.
Dado un Colaborador, el tipo de producto asignado.
Conocer los objetos de tipo Producto que están creados en todo momento.
El ingeniero controla y conoce las actividades de cada colaborador.
Escribir la clase Ingeniero y la clase Colaborador.
La clase principal de la aplicación (método main()) crea los objetos del sistema y los relaciona. Creará el objeto Ingeniero, los objetos
Colaborador y los diversos tipos de productos. Además, asignará información a los objetos, por ejemplo el agua consumida por un objeto
Flor.
Ignacio Zahonero Martínez
Luis Joyanes Aguilar
57
EJERCICIOS(V)
7.
Suponer que se desea realizar una aplicación para desarrollar cuentos interactivos. Para desarrollar un cuento se necesita crear los
personajes. Cada personaje tendrá un nombre, sexo y edad. Además los personajes pueden ser: princesas, príncipes, o monstruos.
En el caso de las princesas se necesita guardar el color del vestido, si lleva zapatos o no y el color del pelo. En el caso de los
príncipes, se necesita si lleva espada y el color del caballo. Por último, para los monstruos se necesita el tamaño, el color, y si tiene
pelo o no.
Se establecen dos requerimientos de la aplicación:
•
Listar el nombre de todos los cuentos en los que ha participado un personaje en concreto.
•
Listar todos los personajes que han participado en algún cuento mayores de 16 años.
La aplicación tendrá que ir almacenando información sobre los cuentos que se han contado, como por ejemplo el título, la duración y el tema
principal, así como los personajes que han participado en él.
Pasos a seguir:
1.
Encontrar las clase.
2.
Realizar el diagrama de clases en notación UML.
3.
Implementar las clases de la jerarquía de personajes. Definir constructores para las clases, métodos para el interfaz. Encontrar algún
método polimórfico. Escribir una clase principal para probar las clases.
4.
Implementar la clase Cuento (en el mismo proyecto). Definir constructor(es). Los atributos y métodos aparecen en el documento de
requisitos. Implementar la clase principal de prueba.
5.
Escribir un programa (clase principal) que cree objetos Cuento, asocie sus personajes. Los objetos guardarlos en un contenedor. A
continuación, pedir un personaje y listar los nombres de los cuentos en los que ha participado (enviando mensajes desde el objeto
personaje). También, listar todos los personajes que han participado en algún cuento, cuya edad sea mayor de 16 años.
Ignacio Zahonero Martínez
Luis Joyanes Aguilar
58