SO04 - Diseño de tipos

Anuncio
FUNDAMENTOS DE PROGRAMACIÓN
PRÁCTICA 4: DISEÑO DE TIPOS
Curso: 2010/11
Versión: 1.0.1
SOLUCIONES
Ejercicios 1, 2 y 3
Definición de interfaces
Tipo Punto
public interface Punto extends Copiable<Punto>, Comparable<Punto>{
public Double getX();
public Double getY();
public void setX(Double x1);
public void setY(Double y1);
}
Tipo Circulo
public interface Circulo extends Comparable<Circulo>,Copiable<Circulo> {
public Double getRadio();
public Punto getCentro();
public void setRadio(Double r);
public void setCentro(Punto p);
public Double getArea();
public Double getLongitud();
}
Tipo Persona
public interface Persona extends Comparable<Persona>, Copiable<Persona> {
String getNombre();
String getApellidos() ;
String getDNI() ;
Integer getEdad();
Double getEstatura();
Character getSexo();
void setEdad(Integer e);
void setEstatura(Double e);
void setSexo(Character s);
}
Implementación de las clases con los esquemas propuestos
Implementación de Punto
public class PuntoImpl implements Punto {
private Double x;
private Double y;
public PuntoImpl (Double x1, Double y1) {
if(x1==null || y1 == null){
throw new IllegalArgumentException(
"Algún parámetro es null");
}
Práctica 4: Diseño de tipos
x=x1;
y=y1;
}
public Double getX() {
return x;
}
public Double getY() {
return y;
}
public void setX(Double x1) {
if(x1==null){
throw new IllegalArgumentException(
"Algún parámetro es null");
}
x=x1;
}
public void setY(Double y1) {
if(y1 == null){
throw new IllegalArgumentException(
"Algún parámetro es null");
}
y=y1;
}
public boolean equals (Object o){
boolean res = false;
if(o instanceof Punto){
Punto p = (Punto) o;
res = getX().equals(p.getX()) &&
getY().equals(p.getY());
}
return res;
}
public String toString() {
String s="("+getX()+","+ getY()+")";
return s;
}
public int hashCode(){
return getX().hashCode() * 31 + getY().hashCode();
}
public int compareTo(Punto p){
int cmp = getX().compareTo(p.getX());
if(cmp == 0){
cmp = getY().compareTo(p.getY());
}
return cmp;
}
public Punto clone() {
Punto copia = null;
try {
copia = (Punto) super.clone();
} catch (CloneNotSupportedException e) {
e.printStackTrace();
}
return copia;
}
}
Implementación de Circulo
public class CirculoImpl implements Circulo {
private Double radio;
2
Práctica 4: Diseño de tipos
private Punto centro;
public CirculoImpl(Double r, Punto p){
if(r==null || p == null || r <= 0){
throw new IllegalArgumentException(
"Algún parámetro es incorrecto");
}
radio = r;
centro = p;
}
public Double getRadio(){
return radio;
}
public Punto getCentro(){
return centro;
}
public void setRadio(Double r){
radio = r;
}
public void setCentro(Punto p){
centro = p;
}
public Double getArea(){
Double res = Math.PI * Math.pow(radio, 2);
return res;
}
public Double getLongitud(){
return 2 * Math.PI * radio;
}
public Circulo clone() {
Circulo copia = null;
try {
copia = (Circulo) super.clone();
} catch (CloneNotSupportedException e) {
e.printStackTrace();
}
return copia;
}
public int compareTo(Circulo e) {
int cmp = this.getRadio().compareTo(e.getRadio());
if (cmp == 0) {
cmp = this.getCentro().compareTo(e.getCentro());
}
return cmp;
}
public String toString() {
return "Radio : " + radio + getCentro();
}
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + getCentro().hashCode();
result = prime * result + getRadio().hashCode();
return result;
}
public boolean equals(Object obj) {
boolean res = false;
if (obj instanceof Circulo){
Circulo other = (Circulo) obj;
res = getCentro().equals(other.getCentro())&&
getRadio().equals(other.getRadio());
3
Práctica 4: Diseño de tipos
}
return res;
}
}
Implementación de Persona
public class PersonaImpl implements Persona {
private String nombre;
private String apellidos ;
private String dni ;
private Integer edad;
private Double estatura;
private Character sexo;
public PersonaImpl(String nombre, String apellidos, String dni,
Integer edad, Double estatura, Character sexo) {
super();
if(nombre==null || apellidos == null || dni == null ||
edad == null || estatura == null || sexo == null ||
estatura <= 0.0 || edad < 0){
throw new IllegalArgumentException(
"Algún parámetro es inapropiado");
}
this.nombre = nombre;
this.apellidos = apellidos;
this.dni = dni;
this.edad = edad;
this.estatura = estatura;
this.sexo = sexo;
}
public Integer getEdad() {
return edad;
}
public void setEdad(Integer edad) {
if( edad == null || edad < 0){
throw new IllegalArgumentException(
"Algún parámetro es inapropiado");
}
this.edad = edad;
}
public String getNombre() {
return nombre;
}
public String getApellidos() {
return apellidos;
}
public String getDNI() {
return dni;
}
public Character getSexo() {
return sexo;
}
public Double getEstatura() {
return estatura;
}
public void setEstatura(Double estatura) {
if(estatura == null || estatura <= 0.0){
throw new IllegalArgumentException(
"Algún parámetro es inapropiado");
}
4
Práctica 4: Diseño de tipos
this.estatura = estatura;
}
public void setSexo(Character sexo) {
this.sexo = sexo;
}
public Persona clone() {
Persona copia = null;
try {
copia = (Persona) super.clone();
} catch (CloneNotSupportedException e) {
e.printStackTrace();
}
return copia;
}
public int compareTo(Persona e) {
int cmp = this.getApellidos().compareTo(e.getApellidos());
if (cmp == 0) {
cmp = this.getNombre().compareTo(e.getNombre());
}
if (cmp == 0) {
cmp = this.getDNI().compareTo(e.getDNI());
}
return cmp;
}
public String toString() {
return "" + nombre +", " + apellidos + " (" + dni + ")";
}
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + apellidos.hashCode();
result = prime * result + dni.hashCode();
result = prime * result + nombre.hashCode();
return result;
}
public boolean equals(Object obj) {
boolean res = false;
if (obj instanceof PersonaImpl){
Persona other = (Persona) obj;
res = getApellidos().equals(other.getApellidos())
&& getDNI().equals(other.getDNI())
&& getNombre().equals(other.getNombre());
}
return res;
}
}
Implementación de las clases con el generador de código de Eclipse
Obsérvese que el generador automático de Eclipse utiliza esquemas y criterios que pueden
no coincidir con nuestros diseños. En concreto,
1. En los constructores no se gestionan excepciones; en nuestro código sí, por ejemplo
no admitir null en los atributos.
2. Los métodos get y set los nombra get/set, la inicial del atributo en mayúscula y el
resto de caracteres en minúscula; esto fallaría en el caso del método getDNI de
nuestra interfaz.
3. En el método toString su formato estándar es NombreClase : nombre atributo
valor …
5
Práctica 4: Diseño de tipos
4. El método equals solo trabaja con los de la misma implementación y no
considerando la misma interfaz como en nuestro esquema. El método sí gestiona
adecuadamente los atributos que pudiesen estar a null en el objeto a comparar.
5. El método hashCode gestiona adecuadamente los atributos que pudiesen estar a
null en el objeto.
Implementación de Punto usando el generador de código
public class PuntoImpl2 implements Punto {
private Double x;
private Double y;
public PuntoImpl2(Double x, Double y) {
super();
this.x = x;
this.y = y;
}
public Double getX() {
return x;
}
public void setX(Double x) {
this.x = x;
}
public Double getY() {
return y;
}
public void setY(Double y) {
this.y = y;
}
public String toString() {
return "PuntoImpl2 [x=" + x + ", y=" + y + "]";
}
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + ((x == null) ? 0 : x.hashCode());
result = prime * result + ((y == null) ? 0 : y.hashCode());
return result;
}
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (!(obj instanceof PuntoImpl2))
return false;
PuntoImpl2 other = (PuntoImpl2) obj;
if (x == null) {
if (other.x != null)
return false;
} else if (!x.equals(other.x))
return false;
if (y == null) {
if (other.y != null)
return false;
} else if (!y.equals(other.y))
return false;
return true;
}
6
Práctica 4: Diseño de tipos
public int compareTo(Punto e) {
int cmp = this.getX().compareTo(e.getX());
if (cmp == 0) {
cmp = this.getY().compareTo(e.getY());
}
return cmp;
}
public Punto clone(){
Punto copia=null;
try{
copia=(Punto)super.clone();
}catch(CloneNotSupportedException e){e.printStackTrace();}
return copia;
}
}
Implementación de Circulo usando el generador de código
public class CirculoImpl2 implements Circulo {
private static final Double PI = new Double(3.1416);
private Double radio;
private Punto centro;
public CirculoImpl2(Double r, Punto p){
if(r==null || p == null || r <= 0){
throw new IllegalArgumentException(
"Algún parámetro es incorrecto");
}
radio = r;
centro = p;
}
public Double getRadio(){
return radio;
}
public Punto getCentro(){
return centro;
}
public void setRadio(Double r){
radio = r;
}
public void setCentro(Punto p){
centro = p;
}
public Double getArea(){
Double res = PI * Math.pow(radio, 2);
return res;
}
public Double getLongitud(){
return 2 * PI * radio;
}
public Circulo clone() {
Circulo copia = null;
try {
copia = (Circulo) super.clone();
} catch (CloneNotSupportedException e) {
e.printStackTrace();
}
return copia;
}
public int compareTo(Circulo e) {
int cmp = this.getRadio().compareTo(e.getRadio());
7
Práctica 4: Diseño de tipos
if (cmp == 0) {
cmp = this.getCentro().compareTo(e.getCentro());
}
return cmp;
}
public String toString() {
return "CirculoImpl [radio="+radio+",centro="+centro+"]";
}
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + ((centro == null) ? 0 :
centro.hashCode());
result = prime * result + ((radio == null) ? 0 :
radio.hashCode());
return result;
}
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (!(obj instanceof CirculoImpl2))
return false;
CirculoImpl2 other = (CirculoImpl2) obj;
if (centro == null) {
if (other.centro != null)
return false;
} else if (!centro.equals(other.centro))
return false;
if (radio == null) {
if (other.radio != null)
return false;
} else if (!radio.equals(other.radio))
return false;
return true;
}
}
Implementación de Persona usando el generador de código
public class PersonaImpl2 implements Persona {
private String nombre;
private String apellidos ;
private String dni ;
private Integer edad;
private Double estatura;
private Character sexo;
public PersonaImpl2(String nombre, String apellidos, String dni,
Integer edad, Double estatura, Character sexo) {
super();
this.nombre = nombre;
this.apellidos = apellidos;
this.dni = dni;
this.edad = edad;
this.estatura = estatura;
this.sexo = sexo;
}
public Integer getEdad() {
8
Práctica 4: Diseño de tipos
return edad;
}
public void setEdad(Integer edad) {
if( edad == null || edad < 0){
throw new IllegalArgumentException(
"Algún parámetro es inapropiado");
}
this.edad = edad;
}
public String getNombre() {
return nombre;
}
public String getApellidos() {
return apellidos;
}
public Character getSexo() {
return sexo;
}
public String getDNI() {
return dni;
}
public Double getEstatura() {
return estatura;
}
public void setEstatura(Double estatura) {
if(estatura == null || estatura <= 0.0){
throw new IllegalArgumentException(
"Algún parámetro es inapropiado");
}
this.estatura = estatura;
}
public void setSexo(Character sexo) {
this.sexo = sexo;
}
public Persona clone() {
Persona copia = null;
try {
copia = (Persona) super.clone();
} catch (CloneNotSupportedException e) {
e.printStackTrace();
}
return copia;
}
public int compareTo(Persona e) {
int cmp = this.getApellidos().compareTo(e.getApellidos());
if (cmp == 0) {
cmp = this.getNombre().compareTo(e.getNombre());
}
if (cmp == 0) {
cmp = this.getDNI().compareTo(e.getDNI());
}
return cmp;
}
public String toString() {
return "PersonaImpl2 [nombre=" + nombre + ", apellidos=" +
apellidos + ", dni=" + dni + "]";
}
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + ((apellidos == null) ? 0 :
9
Práctica 4: Diseño de tipos
apellidos.hashCode());
result = prime * result + ((dni == null) ? 0 :
dni.hashCode());
result = prime * result + ((nombre == null) ? 0 :
nombre.hashCode());
return result;
}
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (!(obj instanceof PersonaImpl2))
return false;
PersonaImpl2 other = (PersonaImpl2) obj;
if (apellidos == null) {
if (other.apellidos != null)
return false;
} else if (!apellidos.equals(other.apellidos))
return false;
if (dni == null) {
if (other.dni != null)
return false;
} else if (!dni.equals(other.dni))
return false;
if (nombre == null) {
if (other.nombre != null)
return false;
} else if (!nombre.equals(other.nombre))
return false;
return true;
}
}
Ejercicio 4
Tipo Racional
public interface Racional extends Comparable<Racional>,
Copiable<Racional> {
Integer getNumerador();
Integer getDenominador();
Double getValorReal();
void setNumerador(Integer a);
void setDenominador(Integer a);
void suma(Racional r);
void resta(Racional r);
void multiplica(Racional r);
void divide(Racional r);
void invierte();
}
Implementación de Racional
public class RacionalImpl implements Racional {
private Integer numerador;
private Integer denominador;
public RacionalImpl() {
numerador = 1;
10
Práctica 4: Diseño de tipos
denominador = 1;
}
public RacionalImpl(Integer a) {
if( a == null) throw new IllegalArgumentException(
"Parametro null");
numerador = a;
denominador = 1;
}
public RacionalImpl(Integer a, Integer b) {
if( a == null || b == null || b == 0 )
throw new IllegalArgumentException(
"Parametros null o el divisor es cero");
if (b <0){
numerador = -a;
denominador = -b;
} else {
numerador = a;
denominador = b;
}
}
public Integer getNumerador(){
return numerador;
}
public Integer getDenominador(){
return denominador;
}
public Double getValorReal(){
return ((double)getNumerador())/getDenominador();
}
public void setNumerador(Integer a) {
numerador = a;
}
public void setDenominador(Integer b){
if( b == 0) throw new IllegalArgumentException(
"El Divisor no puede ser cero");
denominador = b;
}
public void suma(Racional r) {
Integer a= getNumerador()*r.getDenominador() +
getDenominador()*r.getNumerador();
Integer b = getDenominador()*r.getDenominador();
setNumerador(a);
setDenominador( b);
}
public void resta(Racional r){
Integer a=getNumerador()*r.getDenominador()getDenominador()*r.getNumerador();
Integer b = getDenominador()*r.getDenominador();
setNumerador(a);
setDenominador( b);
}
public void multiplica(Racional r){
Integer a = getNumerador()*r.getNumerador();
Integer b = getDenominador()*r.getDenominador();
setNumerador(a);
setDenominador( b);
}
public void divide(Racional r){
if(r.getNumerador() == 0) throw new ArithmeticException(
"No se puede dividir entre cero");
Integer a = getNumerador()*r.getDenominador();
11
Práctica 4: Diseño de tipos
Integer b = getDenominador()*r.getNumerador();
setNumerador(a);
setDenominador(b);
}
public void invierte(){
if(getNumerador() == 0) throw new ArithmeticException(
"No se puede invertir si el numerador es cero");
Integer a = getNumerador();
Integer b = getDenominador();
if( getNumerador() > 0){
setNumerador(a);
setDenominador( b);
} else {
setNumerador(-a);
setDenominador( -b);
}
}
public Racional clone(){
Racional copia = null;
try {
copia = (Racional) super.clone();
}catch(CloneNotSupportedException e){
e.printStackTrace();
}
return copia;
}
public String toString(){
String s = getNumerador().toString();
if(!getDenominador().equals(1)){
s = s + "/" + getDenominador();
}
return s;
}
public boolean equals (Object r){
boolean res = false;
if(r instanceof Racional){
Racional r1 = (Racional) r;
Integer prod1 = getNumerador()*r1.getDenominador();
Integer prod2 = getDenominador()*r1.getNumerador();
res = prod1.equals(prod2);
}
return res;
}
public int hashCode(){
Integer n = getNumerador();
Integer d = getDenominador();
Integer mcd = Enteros.mcd(n,d);
n = n/mcd;
d = d/mcd;
return n.hashCode()*31 + d.hashCode();
}
public int compareTo(Racional r){
Integer prod1 = getNumerador()*r.getDenominador();
Integer prod2 = getDenominador()*r.getNumerador();
return prod1.compareTo(prod2);
}
}
12
Descargar