tema 3 – herencia en java – parte 2 -...

49
Tema 3 – Herencia en Java – Parte 2 Programación Orientada a Objetos Curso 2015/2016

Upload: others

Post on 21-Apr-2020

18 views

Category:

Documents


0 download

TRANSCRIPT

Page 1: Tema 3 – Herencia en Java – Parte 2 - UMdis.um.es/docencia/poo/wiki/lib/exe/fetch.php?media=curso2015:tem… · indicando que no se puede heredar de ella. ... la interfaz vacía

Tema 3 – Herencia en Java – Parte 2

Programación Orientada a Objetos

Curso 2015/2016

Page 2: Tema 3 – Herencia en Java – Parte 2 - UMdis.um.es/docencia/poo/wiki/lib/exe/fetch.php?media=curso2015:tem… · indicando que no se puede heredar de ella. ... la interfaz vacía

Programación Orientada a Objetos 2Curso 2015/2016

Contenido

• Restringir la herencia.

• Visibilidad protegida.

• Clases abstractas.

• Interfaces.

• Clase Object.

• Autoboxing.

• Copia de objetos.

• Igualdad de objetos.

Page 3: Tema 3 – Herencia en Java – Parte 2 - UMdis.um.es/docencia/poo/wiki/lib/exe/fetch.php?media=curso2015:tem… · indicando que no se puede heredar de ella. ... la interfaz vacía

Programación Orientada a Objetos 3Curso 2015/2016

Restringir la herencia

� ¿Es seguro permitir que los subtipos redefinan cualquier

método?

� La redefinición incorrecta del algoritmo del método

liquidar() podría comprometer la consistencia y

seguridad de la aplicación.

� En Java se puede aplicar el modificador final a un

método para indicar que no puede ser redefinido.

� Asimismo, el modificador final es aplicable a una clase

indicando que no se puede heredar de ella.

Page 4: Tema 3 – Herencia en Java – Parte 2 - UMdis.um.es/docencia/poo/wiki/lib/exe/fetch.php?media=curso2015:tem… · indicando que no se puede heredar de ella. ... la interfaz vacía

Programación Orientada a Objetos 4Curso 2015/2016

Restringir la herencia

public class Deposito {

public final double liquidar() {

return getCapital() + getIntereses();

}

}

� El algoritmo del método liquidar es el mismo para todos

los depósitos, no se puede redefinir.

Page 5: Tema 3 – Herencia en Java – Parte 2 - UMdis.um.es/docencia/poo/wiki/lib/exe/fetch.php?media=curso2015:tem… · indicando que no se puede heredar de ella. ... la interfaz vacía

Programación Orientada a Objetos 5Curso 2015/2016

Visibilidad para la herencia

� Puede tener sentido que algunos atributos y métodos de

una clase, sin ser públicos, puedan ser accesibles a las

subclases.

� Ejemplo: el atributo capital de Deposito.

� Nivel de visibilidad protegido (protected): visibilidad para

las subclases y las clases del mismo paquete.

� Es discutible el uso de visibilidad protegida para los

atributos

� En contra de la ocultación de la información.

� Para los métodos, la visibilidad protegida es útil.

Page 6: Tema 3 – Herencia en Java – Parte 2 - UMdis.um.es/docencia/poo/wiki/lib/exe/fetch.php?media=curso2015:tem… · indicando que no se puede heredar de ella. ... la interfaz vacía

Programación Orientada a Objetos 6Curso 2015/2016

Niveles de visibilidad

� En Java, los niveles de visibilidad son incrementales

private

() paquete

protected

public public � todo el código

protected � clase + paquete + subclases

(nada) � clase + paquete

private � clase

Page 7: Tema 3 – Herencia en Java – Parte 2 - UMdis.um.es/docencia/poo/wiki/lib/exe/fetch.php?media=curso2015:tem… · indicando que no se puede heredar de ella. ... la interfaz vacía

Programación Orientada a Objetos 7Curso 2015/2016

Revisión redefinición de métodos

� Al redefinir un método podemos cambiar su

implementación (refinamiento, reemplazo).

� También se puede cambiar el nivel de visibilidad de la

declaración para incrementarlo.

� Es posible cambiar el tipo de retorno a otro más

específico (subclase) � Regla covariante.

� Ejemplo: en DepositoGarantizado podemos obligar a

que los titulares sean de tipo PersonaPreferente,

subclase de Persona.

� En este caso, el método de consulta se redefine como

PersonaPreferente getTitular().

Page 8: Tema 3 – Herencia en Java – Parte 2 - UMdis.um.es/docencia/poo/wiki/lib/exe/fetch.php?media=curso2015:tem… · indicando que no se puede heredar de ella. ... la interfaz vacía

Programación Orientada a Objetos 8Curso 2015/2016

Clases abstractas

� Motivación:

� En la aplicación bancaria observamos que tanto las cuentas como los depósitos tienen dos características en común: tienen un titular y pagan impuestos.

� Identificamos el concepto Producto Financiero y definimos una clase que sea padre de Deposito y Cuenta (Generalización).

� Se realiza la refactorización del código de las clases Deposito y Cuenta para subir la funcionalidad relativa al

titular a la nueva clase.

� Además se introduce el método getImpuestos() que

calcula los impuestos como el 21% del beneficio del producto.

Page 9: Tema 3 – Herencia en Java – Parte 2 - UMdis.um.es/docencia/poo/wiki/lib/exe/fetch.php?media=curso2015:tem… · indicando que no se puede heredar de ella. ... la interfaz vacía

Programación Orientada a Objetos 9Curso 2015/2016

Jerarquía de herencia

Page 10: Tema 3 – Herencia en Java – Parte 2 - UMdis.um.es/docencia/poo/wiki/lib/exe/fetch.php?media=curso2015:tem… · indicando que no se puede heredar de ella. ... la interfaz vacía

Programación Orientada a Objetos 10Curso 2015/2016

Clase ProductoFinanciero

public class ProductoFinanciero {

private Persona titular;

public ProductoFinanciero(Persona titular) {

this.titular = titular;

}

public Persona getTitular() { return titular; }

public double getImpuestos() {

return getBeneficio() * 0.21;

}

}

Page 11: Tema 3 – Herencia en Java – Parte 2 - UMdis.um.es/docencia/poo/wiki/lib/exe/fetch.php?media=curso2015:tem… · indicando que no se puede heredar de ella. ... la interfaz vacía

Programación Orientada a Objetos 11Curso 2015/2016

Clases abstractas

� ¿Cómo se calcula el beneficio de un producto financiero?

� ¿Tiene sentido incluir una implementación por defecto que

retorne cero?

� El método getBeneficio() no puede ser implementado

en la clase ProductoFinanciero.

� El método getBeneficio() es abstracto.

�Es responsabilidad de las subclases implementarlo

adecuadamente.

� La clase ProductoFinanciero es abstracta, ya que tiene

un método abstracto.

Page 12: Tema 3 – Herencia en Java – Parte 2 - UMdis.um.es/docencia/poo/wiki/lib/exe/fetch.php?media=curso2015:tem… · indicando que no se puede heredar de ella. ... la interfaz vacía

Programación Orientada a Objetos 12Curso 2015/2016

Clase ProductoFinanciero

public abstract class ProductoFinanciero {

private Persona titular;

public ProductoFinanciero(Persona titular) {

this.titular = titular;

}

public Persona getTitular() { return titular; }

public double getImpuestos() {

return getBeneficio() * 0.21;

}

public abstract double getBeneficio();

}

Page 13: Tema 3 – Herencia en Java – Parte 2 - UMdis.um.es/docencia/poo/wiki/lib/exe/fetch.php?media=curso2015:tem… · indicando que no se puede heredar de ella. ... la interfaz vacía

Programación Orientada a Objetos 13Curso 2015/2016

Jerarquía de herencia

Page 14: Tema 3 – Herencia en Java – Parte 2 - UMdis.um.es/docencia/poo/wiki/lib/exe/fetch.php?media=curso2015:tem… · indicando que no se puede heredar de ella. ... la interfaz vacía

Programación Orientada a Objetos 14Curso 2015/2016

Clases abstractas

� Una clase abstracta define un tipo, como cualquier otra

clase.

� Sin embargo, no se pueden construir objetos de una

clase abstracta.

� Los constructores sólo tienen sentido para ser utilizados

en las subclases.

� Justificación de una clase abstracta:

� declara o hereda métodos abstractos

� y/o representa un concepto abstracto para el que no tiene

sentido crear objetos: ¿un objeto producto financiero o figura

geométrica?

Page 15: Tema 3 – Herencia en Java – Parte 2 - UMdis.um.es/docencia/poo/wiki/lib/exe/fetch.php?media=curso2015:tem… · indicando que no se puede heredar de ella. ... la interfaz vacía

Programación Orientada a Objetos 15Curso 2015/2016

Clases parcialmente abstractas

� Clases que tienen métodos abstractos y efectivos

(implementados)

� Ejemplo: Producto Financiero.

� Método plantilla: método efectivo que hace uso de

métodos abstractos.

� Ejemplo: getImpuestos().

� Importante mecanismo para definir código reutilizable.

� Definen comportamiento común a todos los

descendientes.

Page 16: Tema 3 – Herencia en Java – Parte 2 - UMdis.um.es/docencia/poo/wiki/lib/exe/fetch.php?media=curso2015:tem… · indicando que no se puede heredar de ella. ... la interfaz vacía

Programación Orientada a Objetos 16Curso 2015/2016

Limitaciones de la herencia

� La compatibilidad de tipos que proporciona la herencia

resulta útil: variables y estructuras polimórficas, código

reutilizable, etc.

� Los tipos que representan los objetos de una clase son:

� El tipo que define la clase.

� El tipo de cada uno de sus ascendientes.

� La herencia simple limita el número de tipos que pueden

representar los objetos de una clase.

� Solución: interfaces

Page 17: Tema 3 – Herencia en Java – Parte 2 - UMdis.um.es/docencia/poo/wiki/lib/exe/fetch.php?media=curso2015:tem… · indicando que no se puede heredar de ella. ... la interfaz vacía

Programación Orientada a Objetos 17Curso 2015/2016

Interfaces

� Construcción proporcionada por Java para la definición de tipos (sin implementación).

� Se dice que una clase implementa una interfaz.

� El número de interfaces que puede implementar una clase no está limitado (implementación múltiple de interfaces).

� Los tipos que representan los objetos de una clase pueden ser ampliados con la implementación de interfaces.

Page 18: Tema 3 – Herencia en Java – Parte 2 - UMdis.um.es/docencia/poo/wiki/lib/exe/fetch.php?media=curso2015:tem… · indicando que no se puede heredar de ella. ... la interfaz vacía

Programación Orientada a Objetos 18Curso 2015/2016

Interfaz Amortizable

� Ejemplo: un deposito es amortizable si permite rescatar parte del capital antes del vencimiento.

� Se define este tipo de depósitos como una interfaz.

public interface Amortizable {

boolean amortizar(double cantidad);}

Page 19: Tema 3 – Herencia en Java – Parte 2 - UMdis.um.es/docencia/poo/wiki/lib/exe/fetch.php?media=curso2015:tem… · indicando que no se puede heredar de ella. ... la interfaz vacía

Programación Orientada a Objetos 19Curso 2015/2016

Interfaz Amortizable

� Por defecto, en una interfaz la visibilidad de las declaraciones es pública.

� Las interfaces pueden incorporar declaraciones

(simplificadas) de constantes:

public interface Amortizable {

double LIMITE = 10000.0;

boolean amortizar(double cantidad);

}

Page 20: Tema 3 – Herencia en Java – Parte 2 - UMdis.um.es/docencia/poo/wiki/lib/exe/fetch.php?media=curso2015:tem… · indicando que no se puede heredar de ella. ... la interfaz vacía

Programación Orientada a Objetos 20Curso 2015/2016

Implementación de una interfaz

� Ejemplo: sólo los depósitos garantizados y los penalizables pueden ser amortizables.

� Las dos clases implementan la interfaz:

public class DepositoPenalizable extends Deposito implements Amortizable {

…@Overridepublic boolean amortizar(double cantidad) {

if (cantidad > capital) return false;

capital = capital - cantidad;return true;

}}

Page 21: Tema 3 – Herencia en Java – Parte 2 - UMdis.um.es/docencia/poo/wiki/lib/exe/fetch.php?media=curso2015:tem… · indicando que no se puede heredar de ella. ... la interfaz vacía

Programación Orientada a Objetos 21Curso 2015/2016

Interfaces

Page 22: Tema 3 – Herencia en Java – Parte 2 - UMdis.um.es/docencia/poo/wiki/lib/exe/fetch.php?media=curso2015:tem… · indicando que no se puede heredar de ella. ... la interfaz vacía

Programación Orientada a Objetos 22Curso 2015/2016

Extensión de interfaces

� Una interfaz puede extender otras interfaces:

public interface Flexible extends Amortizable, Incrementable {

void actualizarTipoInteres(double tipo);

}

Page 23: Tema 3 – Herencia en Java – Parte 2 - UMdis.um.es/docencia/poo/wiki/lib/exe/fetch.php?media=curso2015:tem… · indicando que no se puede heredar de ella. ... la interfaz vacía

Programación Orientada a Objetos 23Curso 2015/2016

Interfaces – Resumen

� Las interfaces definen tipos que deben ser implementados por clases.� Amortizable deposito = new DepositoPenalizable(…);

� Si una clase no implementa algún método de una interfaz debe declararse abstracta.

� Una interfaz define un tipo, pero no se pueden construir objetos de una interfaz:� Amortizable deposito = new Amortizable(); // Error

� Las interfaces resuelven la limitación de tipos impuesta por la herencia simple.

Page 24: Tema 3 – Herencia en Java – Parte 2 - UMdis.um.es/docencia/poo/wiki/lib/exe/fetch.php?media=curso2015:tem… · indicando que no se puede heredar de ella. ... la interfaz vacía

Programación Orientada a Objetos 24Curso 2015/2016

Clase Object

� El lenguaje Java define la clase Object como raíz de la

jerarquía de todas las clases del lenguaje.

� Todas las clases heredan directa o indirectamente de la

clase Object:

� Si una clase no hereda de ninguna otra, el compilador añade extends Object a su declaración.

� � Una variable de tipo Object puede apuntar a cualquier

tipo del lenguaje:

� Objetos creados a partir de clases.

� Tipos primitivos gracias al autoboxing.

Page 25: Tema 3 – Herencia en Java – Parte 2 - UMdis.um.es/docencia/poo/wiki/lib/exe/fetch.php?media=curso2015:tem… · indicando que no se puede heredar de ella. ... la interfaz vacía

Programación Orientada a Objetos 25Curso 2015/2016

Clase Object y Autoboxing

� El autoboxing es un mecanismo automático encargado de convertir objetos en tipos primitivos y viceversa.

� De este modo, una referencia de tipo Object puede

apuntar a cualquier tipo de datos.

� Conversión de tipos primitivos a objetos:

� Java construye objetos envoltorio donde almacenar los valores primitivos.

� Para cada tipo primitivo hay una clase envoltorio: Integerpara int, Double para double, etc.

� La conversión de un objeto en un tipo primitivo requiere hacer el casting al tipo envoltorio.

Object obj = 3;

int entero = (Integer)obj;

Page 26: Tema 3 – Herencia en Java – Parte 2 - UMdis.um.es/docencia/poo/wiki/lib/exe/fetch.php?media=curso2015:tem… · indicando que no se puede heredar de ella. ... la interfaz vacía

Programación Orientada a Objetos 26Curso 2015/2016

Métodos clase Object

� En Java, la clase Object incluye las características

comunes a todos los objetos:

� public boolean equals(Object obj)

� Igualdad de objetos

� protected Object clone()

� Clonación de objetos

� public String toString()

� Representación textual de un objeto

� public final Class getClass()

� Clase a partir de la que ha sido instanciado un objeto.

� public int hashCode()

� Código hash utilizado en las colecciones.

Page 27: Tema 3 – Herencia en Java – Parte 2 - UMdis.um.es/docencia/poo/wiki/lib/exe/fetch.php?media=curso2015:tem… · indicando que no se puede heredar de ella. ... la interfaz vacía

Programación Orientada a Objetos 27Curso 2015/2016

Copia de objetos

� La asignación de referencias (=) copia el oid del objeto y no la estructura de datos.

� Para obtener una copia de un objeto hay que aplicar el método clone.

� El método clone está implementado en la clase Object

(es heredado) pero no es aplicable por otras clases (visibilidad protected).

� La clase debe redefinir el método clone para aumentar la visibilidad y crear una copia que se adapte a sus necesidades.

� La implementación de clone() en la clase Object

construye una copia superficial de la instancia actual.

Page 28: Tema 3 – Herencia en Java – Parte 2 - UMdis.um.es/docencia/poo/wiki/lib/exe/fetch.php?media=curso2015:tem… · indicando que no se puede heredar de ella. ... la interfaz vacía

Programación Orientada a Objetos 28Curso 2015/2016

Tipos de copia

� Tipos de copia:

� Copia superficial: los campos de la copia son

exactamente iguales a los del objeto receptor.

� Copia profunda: los campos primitivos de la copia son

iguales y las referencias a objetos son copias

profundas.

� Adaptada a las necesidades de la aplicación.

Page 29: Tema 3 – Herencia en Java – Parte 2 - UMdis.um.es/docencia/poo/wiki/lib/exe/fetch.php?media=curso2015:tem… · indicando que no se puede heredar de ella. ... la interfaz vacía

Programación Orientada a Objetos 29Curso 2015/2016

Copia superficial de Cuenta

� Copia superficial:

� Aliasingincorrecto al compartir las últimas operaciones.

� No deberían tener el mismo código

J. Gomez

87654321

nombre

dni

Objeto Persona

-500010000

123456

100000

titular

codigo

saldo

ultOper

cuenta

123456

100000

titular

codigo

saldo

ultOper

copia

Page 30: Tema 3 – Herencia en Java – Parte 2 - UMdis.um.es/docencia/poo/wiki/lib/exe/fetch.php?media=curso2015:tem… · indicando que no se puede heredar de ella. ... la interfaz vacía

Programación Orientada a Objetos 30Curso 2015/2016

Copia profunda de Cuenta

� Copia profunda:� No tiene sentido duplicar el objeto persona y que

tengan el mismo código.

J. Gomez

87654321

-500010000

123456

100000

titular

codigo

saldo

ultOper

cuenta

123456

100000

titular

codigo

saldo

ultOper

copia

-500010000

J. Gomez

87654321

Page 31: Tema 3 – Herencia en Java – Parte 2 - UMdis.um.es/docencia/poo/wiki/lib/exe/fetch.php?media=curso2015:tem… · indicando que no se puede heredar de ella. ... la interfaz vacía

Programación Orientada a Objetos 31Curso 2015/2016

Copia correcta de Cuenta

� Copia adaptada: cumple los requisitos de la aplicación

J. Gomez

87654321

-500010000

123456

100000

titular

codigo

saldo

ultOper

cuenta

326457

100000

titular

codigo

saldo

ultOper

copia

-500010000

Page 32: Tema 3 – Herencia en Java – Parte 2 - UMdis.um.es/docencia/poo/wiki/lib/exe/fetch.php?media=curso2015:tem… · indicando que no se puede heredar de ella. ... la interfaz vacía

Programación Orientada a Objetos 32Curso 2015/2016

Método clone en Cuenta

public class Cuenta implements Cloneable{

public Cuenta clone(){

Cuenta copia = null;

try{

copia = (Cuenta)super.clone();

copia.codigo = ++ultimoCodigo;

copia.ultimasOperaciones =

Arrays.copyOf(ultimasOperaciones, ultimasOperaciones.length);

}catch (CloneNotSupportedException e){

// No sucede si la clase es Cloneable

System.err.println("La clase no implementa " +"la interfaz Cloneable");

}

return copia;

}

}

Page 33: Tema 3 – Herencia en Java – Parte 2 - UMdis.um.es/docencia/poo/wiki/lib/exe/fetch.php?media=curso2015:tem… · indicando que no se puede heredar de ella. ... la interfaz vacía

Programación Orientada a Objetos 33Curso 2015/2016

Método clone – Recomendaciones

� Aumentar la visibilidad del método clone() para pasar

de protected a public

� Aplicar la regla covariante para establecer el tipo de la clase (el tipo de la copia).

� Realizar una copia basada en la implementación de clone() en Object � copia superficial

� Tratar el error de copia, sin hacer nada (las excepciones se estudian en el tema 5).

� No se produce ningún error de copia si la clase implementa la interfaz vacía Cloneable.

� Adaptar la copia superficial según las necesidades de la aplicación.

Page 34: Tema 3 – Herencia en Java – Parte 2 - UMdis.um.es/docencia/poo/wiki/lib/exe/fetch.php?media=curso2015:tem… · indicando que no se puede heredar de ella. ... la interfaz vacía

Programación Orientada a Objetos 34Curso 2015/2016

Método clone – Recomendaciones

� Ejemplo de adaptación en la clase Cuenta:

� Resuelve el aliasing incorrecto del array.

� Asigna un nuevo código de cuenta a la copia.

� Importante: implementar el método clone() a partir de la copia superficial hace que la implementación sea heredable

� La llamada al método clone() de Object siempre retorna un objeto igual a la instancia actual.

� Una subclase sólo necesitaría redefinir el método si los atributos que aporta no son copiados correctamente con la copia superficial (por ejemplo, aliasing incorrecto).

Page 35: Tema 3 – Herencia en Java – Parte 2 - UMdis.um.es/docencia/poo/wiki/lib/exe/fetch.php?media=curso2015:tem… · indicando que no se puede heredar de ella. ... la interfaz vacía

Programación Orientada a Objetos 35Curso 2015/2016

Método clone – Recomendaciones

� En herencia, aunque el método clone heredado sea correcto, conviene redefinirlo aplicando la regla covariante y llamar a la versión del padre:

� Nota: el casting siempre será correcto, ya que la copia superficial siempre garantiza que el objeto que retorna es del tipo de la instancia actual.

public class CuentaRemunerada extends Cuenta {

public CuentaRemunerada clone(){

return (CuentaRemunerada)super.clone();

}

}

Page 36: Tema 3 – Herencia en Java – Parte 2 - UMdis.um.es/docencia/poo/wiki/lib/exe/fetch.php?media=curso2015:tem… · indicando que no se puede heredar de ella. ... la interfaz vacía

Programación Orientada a Objetos 36Curso 2015/2016

Igualdad de objetos

� El operador == se utiliza para consultar la identidad de

referencias � dos referencias son idénticas si contienen

el mismo oid.

� Identidad entre referencias:� a == c; // True

� a == b; // False

� El método equals permite implementar la igualdad de objetos.

b

a

c

d“uno”

23

“uno”

23

“dos”

23

Page 37: Tema 3 – Herencia en Java – Parte 2 - UMdis.um.es/docencia/poo/wiki/lib/exe/fetch.php?media=curso2015:tem… · indicando que no se puede heredar de ella. ... la interfaz vacía

Programación Orientada a Objetos 37Curso 2015/2016

Método equals

� La implementación en la clase Object consiste en

comprobar la identidad del objeto receptor y el

parámetro.

� Por tanto: a.equals(b); // False

� Es necesario redefinir el método equals en las clases

donde necesitemos la operación de igualdad.

� Sin embargo, hay que elegir la semántica de igualdad

más adecuada para la clase.

public boolean equals(Object obj) {

return this == obj;

}

Page 38: Tema 3 – Herencia en Java – Parte 2 - UMdis.um.es/docencia/poo/wiki/lib/exe/fetch.php?media=curso2015:tem… · indicando que no se puede heredar de ella. ... la interfaz vacía

Programación Orientada a Objetos 38Curso 2015/2016

Tipos de igualdad

� Tipos de igualdad:

� Superficial: los campos primitivos de los dos objetos son

iguales y las referencias a objetos idénticas (comparten los

mismos objetos).

� Profunda: los campos primitivos son iguales y las

referencias son iguales (equals) en profundidad.

� Adaptada a las necesidades de la aplicación.

Page 39: Tema 3 – Herencia en Java – Parte 2 - UMdis.um.es/docencia/poo/wiki/lib/exe/fetch.php?media=curso2015:tem… · indicando que no se puede heredar de ella. ... la interfaz vacía

Programación Orientada a Objetos 39Curso 2015/2016

Método equals en Cuenta

@Override

public boolean equals(Object obj) {

if (obj == null) return false;

if (obj == this) return true;

if (obj.getClass() != this.getClass())

return false;

Cuenta otraCta = (Cuenta)obj;

return (this.codigo == otraCta.codigo) &&

(this.titular == otraCta.titular) &&

(this.saldo == otraCta.saldo) &&

(this.estado == otraCta.estado) &&

(Arrays.equals(this.ultimasOperaciones,otraCta.ultimasOperaciones);

}

Page 40: Tema 3 – Herencia en Java – Parte 2 - UMdis.um.es/docencia/poo/wiki/lib/exe/fetch.php?media=curso2015:tem… · indicando que no se puede heredar de ella. ... la interfaz vacía

Programación Orientada a Objetos 40Curso 2015/2016

Método equals en Cuenta

� Explicación de la implementación:

� 1. Caso trivial: el parámetro es la referencia nula.

� 2. Caso trivial: dos objetos con el mismo oid siempre serán iguales.

� 3. Comprueba que el tipo dinámico de los objetos sea el mismo (método getClass).

� Ejemplo: un depósito garantizado nunca será igual que un depósito estructurado.

� 4. Realiza el casting del parámetro (siempre de tipo Object)

para poder comparar sus atributos

� La consulta del tipo dinámico garantiza el casting correcto.

� 5. Comparación de los atributos

� Nota: un objeto tiene acceso a los atributos de otro de su mismaclase.

Page 41: Tema 3 – Herencia en Java – Parte 2 - UMdis.um.es/docencia/poo/wiki/lib/exe/fetch.php?media=curso2015:tem… · indicando que no se puede heredar de ella. ... la interfaz vacía

Programación Orientada a Objetos 41Curso 2015/2016

Método equals en herencia

� El método equals() heredado en una subclase es correcto

si:

� No aporta nuevos atributos.

� Los atributos que aporta no se tienen en cuenta en la igualdad.

� Si fuera necesario redefinir, debe reutilizarse la versión heredada:

public boolean equals(Object obj) {

if (super.equals(obj) == false) return false;

CuentaRemunerada otroObj = (CuentaRemunerada)obj;

return …; // compara atributos propios

}

Page 42: Tema 3 – Herencia en Java – Parte 2 - UMdis.um.es/docencia/poo/wiki/lib/exe/fetch.php?media=curso2015:tem… · indicando que no se puede heredar de ella. ... la interfaz vacía

Programación Orientada a Objetos 42Curso 2015/2016

Método hashCode

� Devuelve un número que representa el código de dispersión (código hash) de un objeto.

� Importante si los objetos se almacenan en colecciones cuya implementación se basa en una tabla de dispersión (HashMap y HashSet, se estudian en tema 4).

� Importante: la implementación del hashCode() tiene que ser consistente con la implementación del equals()

� Si o1.equals(o2) es true entonceso1.hashCode() == o2.hashCode()

� Lo contrario no tiene por qué ser cierto.

Page 43: Tema 3 – Herencia en Java – Parte 2 - UMdis.um.es/docencia/poo/wiki/lib/exe/fetch.php?media=curso2015:tem… · indicando que no se puede heredar de ella. ... la interfaz vacía

Programación Orientada a Objetos 43Curso 2015/2016

Método hashCode

� La implementación por defecto del método hashCode()deriva el código de dispersión de la dirección de memoria del objeto.

� Importante: si en una clase se redefine el método equals() también hay que redefinir el método hashCode() para que las implementaciones sean consistentes.

� La implementación del método hashCode() se calcula como una combinación del código hash de cada uno de los atributos.

� En el caso de atributos de tipo primitivo se utilizan las clasesenvolventes, salvo para el tipo int.

� Siguiendo la implementación, la probabilidad de que objetos distintos tengan el mismo código de dispersión es muy baja.

Page 44: Tema 3 – Herencia en Java – Parte 2 - UMdis.um.es/docencia/poo/wiki/lib/exe/fetch.php?media=curso2015:tem… · indicando que no se puede heredar de ella. ... la interfaz vacía

Programación Orientada a Objetos 44Curso 2015/2016

Método hashCode en Cuenta

@Override

public int hashCode() {

int primo = 31;

int result = 1;

result = primo * result + codigo;

result = primo * result + ((titular == null) ? 0 :

titular.hashCode());

result = primo * result + new Double(saldo).hashCode();

result = primo * result + ((estado == null) ? 0 :

estado.hashCode());

result = primo * result + Arrays.hashCode(ultimasOperaciones);

return result;

}

� Patrón de redefinición del método hashCode

Page 45: Tema 3 – Herencia en Java – Parte 2 - UMdis.um.es/docencia/poo/wiki/lib/exe/fetch.php?media=curso2015:tem… · indicando que no se puede heredar de ella. ... la interfaz vacía

Programación Orientada a Objetos 45Curso 2015/2016

Método hashCode en herencia

public int hashCode() {

int primo = 31;

int result = super.hashCode();

// añadir atributos utilizados en equals() redefinido

result = primo * result + … ;

return result;

}

� El método hashCode()se redefine en una subclase si se

ha redefinido el método equals()

� � consistencia de las implementaciones.

� La redefinición debe reutilizar la versión heredada.

Page 46: Tema 3 – Herencia en Java – Parte 2 - UMdis.um.es/docencia/poo/wiki/lib/exe/fetch.php?media=curso2015:tem… · indicando que no se puede heredar de ella. ... la interfaz vacía

Programación Orientada a Objetos 46Curso 2015/2016

Método toString en Cuenta

@Override

public String toString() {

return getClass().getName() +

"[codigo = " + codigo +

", titular = "+ titular +

", saldo = "+ saldo +

",ultimasOperaciones = " +

Arrays.toString(ultimasOperaciones) +

"]";

}

� Patrón de redefinición del método toString

Page 47: Tema 3 – Herencia en Java – Parte 2 - UMdis.um.es/docencia/poo/wiki/lib/exe/fetch.php?media=curso2015:tem… · indicando que no se puede heredar de ella. ... la interfaz vacía

Programación Orientada a Objetos 47Curso 2015/2016

Método toString en herencia

� El método toString()debe ser redefinido en una subclase si añade nuevos atributos.

� En caso de redefinición, reutilizar la versión heredada:

� La llamada getClass().getName() siempre mostrarácorrectamente el nombre de la clase:� getClass() retorna el tipo de la instancia actual.

public String toString() {

// añade a la cadena atributos propios

return super.toString() + "[ … ]";

}

Page 48: Tema 3 – Herencia en Java – Parte 2 - UMdis.um.es/docencia/poo/wiki/lib/exe/fetch.php?media=curso2015:tem… · indicando que no se puede heredar de ella. ... la interfaz vacía

Programación Orientada a Objetos 48Curso 2015/2016

Método getClass() vs operador instanceof

� El método getClass()retorna el tipo dinámico de la referencia.

� En general no es recomendado su uso. En su lugar es preferible el operador instanceof para consultar la compatibilidad de tipos.

� Ejemplo: la consulta con getClass() deja fuera los depósitos garantizados que también son depósitos estructurados (incorrecto).

public void setTipoInteresVariable(double tipo,

Deposito[] depositos) {

for (Deposito d : depositos) {

if (d.getClass() == DepositoEstructurado.class) {

}

Page 49: Tema 3 – Herencia en Java – Parte 2 - UMdis.um.es/docencia/poo/wiki/lib/exe/fetch.php?media=curso2015:tem… · indicando que no se puede heredar de ella. ... la interfaz vacía

Programación Orientada a Objetos 49Curso 2015/2016

Seminario 2

� Este tema se completa con el seminario 2 (2ª parte).

� Visibilidad y herencia

� Clase Object

� Autoboxing

� Métodos de la clase Object: igualdad, copia, etc.

� Clases abstractas.

� Interfaces.