Yo creo entender que se han de pedir TODOS los datos al usuario, es decir, no vamos a tener Cabañas, Carpas, Hoteles... predefinidas para ir asignando a los clientes.
El proceso sería:
- Pedir datos Cliente
- Preguntar si quiere Carpa, Cabaña u Hotel...
- Pedir los datos adecuados al alojamiento escogido
- Añadirlo a la colección, controlando que este Cliente no tenga ya previamente asociado ese mismo MedioDeAlojamiento.
Lo que si puede ser un poco confuso son las relaciones entre clases.
Viendo el diagrama, yo las interpreto así:
Clase DatosCliente
public class DatosCliente {
private String rut;
private String nombre;
public DatosCliente(String rut, String nombre) {
this.rut = rut;
this.nombre = nombre;
}
public String getRut() {
return rut;
}
public void setRut(String rut) {
this.rut = rut;
}
public String getNombre() {
return nombre;
}
public void setNombre(String nombre) {
this.nombre = nombre;
}
@Override
public String toString() {
return String.format("RUT: %s -- Nombre: %s", rut, nombre);
}
}
A continuación, la superclase MedioDeAlojamiento.
Esta clase tiene los atributos que son comunes a todos los medios de alojamiento.
La podemos declarar como abstracta porque en principio no nos interesa que se puedan crear objetos directamente de esta clase. Esta clase está destinada a iniciar unas relaciones de herencia, no a funcionar como una entidad individual.
public abstract class MedioDeAlojamiento {
protected DatosCliente cliente;
protected float valorBaseNoche;
protected String tipoTemporada;
protected int cantidadNoches;
public MedioDeAlojamiento(DatosCliente cliente, float valorBaseNoche, String tipoTemporada, int cantidadNoches) {
this.cliente = cliente;
this.valorBaseNoche = valorBaseNoche;
this.tipoTemporada = tipoTemporada;
this.cantidadNoches = cantidadNoches;
}
public DatosCliente getCliente() {
return cliente;
}
public void setCliente(DatosCliente cliente) {
this.cliente = cliente;
}
public float getValorBaseNoche() {
return valorBaseNoche;
}
public void setValorBaseNoche(float valorBaseNoche) {
this.valorBaseNoche = valorBaseNoche;
}
public String getTipoTemporada() {
return tipoTemporada;
}
public void setTipoTemporada(String tipoTemporada) {
this.tipoTemporada = tipoTemporada;
}
public int getCantidadNoches() {
return cantidadNoches;
}
public void setCantidadNoches(int cantidadNoches) {
this.cantidadNoches = cantidadNoches;
}
}
La clase Carpa es hija directa de MedioDeAlojamiento, así que hereda de esta y añade el atributo cantidadPersonas que es propio de Carpa.
Además añade un método equals() para establecer la regla de que dos Carpa son iguales/equivalentes si tienen asociado el mismo cliente.
También un método toString() para mostrar toda la información relativa a esta Carpa
public class Carpa extends MedioDeAlojamiento {
private int cantidadPersonas;
public Carpa(DatosCliente cliente, float valorBaseNoche, String tipoTemporada,
int cantidadNoches, int cantidadPersonas) {
super(cliente, valorBaseNoche, tipoTemporada, cantidadNoches);
this.cantidadPersonas = cantidadPersonas;
}
public int getCantidadPersonas() {
return cantidadPersonas;
}
public void setCantidadPersonas(int cantidadPersonas) {
this.cantidadPersonas = cantidadPersonas;
}
@Override
public String toString() {
StringBuilder cadena = new StringBuilder();
cadena.append("\n\t*** Cliente alojado ***\n" + cliente);
cadena.append("\n\t*** Datos Alojamiento ***\n");
cadena.append("Tipo Alojamiento: Carpa\n");
cadena.append(String.format("Valor Noche: %.2f -- Temporada: %s\n",
valorBaseNoche, tipoTemporada));
cadena.append(String.format("Cantidad Noches: %d -- CantidadPersonas: %d",
cantidadNoches, cantidadPersonas));
return cadena.toString();
}
@Override
public boolean equals(Object objeto) {
/*
* Dos Carpa se consideran "equivalentes
* si tienen asociado el mismo cliente.
*/
if (objeto instanceof Carpa) {
Carpa otraCarpa = (Carpa) objeto;
return cliente.getRut().equals(otraCarpa.getCliente().getRut());
}
else
return false;
}
}
Quedan dos clases, Cabagna y Hotel, pero no son hijas directas de MedioDeAlojamiento.
Hay una clase intermedia llamada Hospederia, con los atributos comunes a estas dos últimas clases.
También la podemos declarar abstracta.
public abstract class Hospederia extends MedioDeAlojamiento {
protected int capacidad;
protected boolean esFumador;
public Hospederia(DatosCliente cliente, float valorBaseNoche, String tipoTemporada,
int cantidadNoches, int capacidad, boolean esFumador) {
super(cliente, valorBaseNoche, tipoTemporada, cantidadNoches);
this.capacidad = capacidad;
this.esFumador = esFumador;
}
}
Ahora sí, las dos últimas clases.
Cabagna agrega el atributo chimenea y posee métodos toString() y equals() apropiados para ella:
public class Cabagna extends Hospederia {
private boolean chimenea;
public Cabagna(DatosCliente cliente, float valorBaseNoche, String tipoTemporada,
int cantidadNoches, int capacidad, boolean esFumador, boolean chimenea) {
super(cliente, valorBaseNoche, tipoTemporada, cantidadNoches, capacidad, esFumador);
this.chimenea = chimenea;
}
public boolean conChimenea() {
return chimenea;
}
public void setChimenea(boolean chimenea) {
this.chimenea = chimenea;
}
@Override
public String toString() {
StringBuilder cadena = new StringBuilder();
cadena.append("\n\t*** Cliente alojado ***\n" + cliente);
cadena.append("\n\t*** Datos Alojamiento ***\n");
cadena.append("Tipo Alojamiento: Cabaña\n");
cadena.append(String.format("Valor Noche: %.2f -- Temporada: %s\n",
valorBaseNoche, tipoTemporada));
cadena.append(String.format("Cantidad Noches: %d -- Capacidad: %d\n", cantidadNoches ,capacidad));
cadena.append(String.format("Fumador: %s -- Chimenea: %s",
esFumador?"SI":"NO", chimenea?"SI":"NO"));
return cadena.toString();
}
@Override
public boolean equals(Object objeto) {
/*
* Dos Cabagna se consideran "equivalentes
* si tienen asociado el mismo cliente.
*/
if (objeto instanceof Cabagna) {
Cabagna otraCabagna = (Cabagna) objeto;
return cliente.getRut().equals(otraCabagna.getCliente().getRut());
}
else
return false;
}
}
Y Hotel, lo mismo, agregando el atributo desayuno:
public class Hotel extends Hospederia {
private boolean conDesayuno;
public Hotel(DatosCliente cliente, float valorBaseNoche, String tipoTemporada, int cantidadNoches, int capacidad,
boolean esFumador, boolean conDesayuno) {
super(cliente, valorBaseNoche, tipoTemporada, cantidadNoches, capacidad, esFumador);
this.conDesayuno = conDesayuno;
}
public boolean conDesayuno() {
return conDesayuno;
}
public void setConDesayuno(boolean conDesayuno) {
this.conDesayuno = conDesayuno;
}
@Override
public String toString() {
StringBuilder cadena = new StringBuilder();
cadena.append("\n\t*** Cliente alojado ***\n" + cliente);
cadena.append("\n\t*** Datos Alojamiento ***\n");
cadena.append("Tipo Alojamiento: Hotel\n");
cadena.append(String.format("Valor Noche: %.2f -- Temporada: %s\n",
valorBaseNoche, tipoTemporada));
cadena.append(String.format("Cantidad Noches: %d -- Capacidad: %d\n", cantidadNoches ,capacidad));
cadena.append(String.format("Fumador: %s -- Desayuno: %s",
esFumador?"SI":"NO", conDesayuno?"SI":"NO"));
return cadena.toString();
}
@Override
public boolean equals(Object objeto) {
/*
* Dos Hotel se consideran "equivalentes
* si tienen asociado el mismo cliente.
*/
if (objeto instanceof Hotel) {
Hotel otroHotel = (Hotel) objeto;
return cliente.getRut().equals(otroHotel.getCliente().getRut());
}
else
return false;
}
}
Con estas clases, se haría un programa con alguna colección, por ejemplo un ArrayList<MedioDeAlojamiento> alojamientos; y habría que ir pidiendo todos los datos necesarios para registrar clientes y alojamientos.
Inténtalo.
Yo luego cuanto tenga tiempo, miraré de hacer mi propia versión.
Un saludo.