Más cosas a comentar ahora que veo a fondo tu código.
Mucho ojo con el orden en que ponemos los parámetros para los constructores.
Para la clase
SalonCasa, has puesto que primero recibe el String de tipoSalon y luego el int de numero televisores:
public SalonCasa(String valorTipoSalon, int valorNumeroDeTelevisores){
tipoSalon=valorTipoSalon;
numeroDeTelevisores=valorNumeroDeTelevisores;}
Vale, eso está muy bien, pero luego cuando quieras construir un objeto de esta clase, recuerda que los parámetros ha de recibirlo en ese mismo orden.
Porque en la clase
Casa, en el constructor donde construyes un
SalonCasa, se los estás pasando invertidos. Y Java también se quejará por esto:
public Casa(double valorSuperficie, String valorDireccion, SalonCasa objetoSalon, CocinaCasa objetoCocina){
superficie=valorSuperficie;
direccion=valorDireccion;
salon=new SalonCasa(objetoSalon.getNumeroDeTelevisores(), objetoSalon.getTipoSalon());
cocina=new CocinaCasa(objetoCocina.getEsIndependiente(), objetoCocina.getNumeroDeFuegos());}
Hay que dárselos en el orden correcto:
public Casa(double valorSuperficie, String valorDireccion, SalonCasa objetoSalon, CocinaCasa objetoCocina){
superficie=valorSuperficie;
direccion=valorDireccion;
salon=new SalonCasa(objetoSalon.getTipoSalon(), objetoSalon.getNumeroDeTelevisores());
cocina=new CocinaCasa(objetoCocina.getEsIndependiente(), objetoCocina.getNumeroDeFuegos());}
Sigamos hablando de este constructor, porque has hecho algo que es muy interesante de comentar.
La forma en que tu constructor inicializa los objetos salon y cocina:
public Casa(double valorSuperficie, String valorDireccion, SalonCasa objetoSalon, CocinaCasa objetoCocina){
superficie=valorSuperficie;
direccion=valorDireccion;
salon=new SalonCasa(objetoSalon.getTipoSalon(), objetoSalon.getNumeroDeTelevisores());
cocina=new CocinaCasa(objetoCocina.getEsIndependiente(), objetoCocina.getNumeroDeFuegos());}
Haciéndolo de esa manera, has de tener en cuenta que estás creando NUEVOS objetos a partir de los que has recibido entre paréntesis.
Es decir, van a tener los mismos valores para los atributos, pero no serán IGUALES. Serán objetos distintos.
Esto no es necesariamente un problema. Habrá ocasiones en que precisamente nos interese hacerlo así, pero normalmente NO.
Cuando un constructor recibe objetos entre paréntesis, normalmente se asignan esos mismos objetos a los atributos, sin crear unos nuevos a partir de ellos:
public Casa(double valorSuperficie, String valorDireccion, SalonCasa objetoSalon, CocinaCasa objetoCocina){
superficie=valorSuperficie;
direccion=valorDireccion;
salon=objetoSalon;
cocina=objetoCocina;}
¿Ves? Entre paréntesis hemos recibido unas "referencias" a unos objetos, y esas mismas referencias las asignamos a los atributos.
Y ya está, con esto es suficiente.
Pero tú lo que has hecho ha sido coger los "valores" de esas referencias, y usarlos para crear objetos nuevos
En otros lenguajes como C/C++, hay de hecho instrucciones específicas para indicar si un parámetro queremos pasarlo por "referencia" o por "valor".
En Java no las hay, simplificaron este aspecto.
Los datos primitivos (int, double, char...) se pasan por "valor" y los objetos de clase se pasan por "referencia".
Lo que tú has hecho ha sido una forma artificial de pasar por "valor" algo que Java solo permite pasar por "referencia"
¿Esto es incorrecto?
No, para nada. Pero implica unas diferencias que debemos tener en cuenta.
Al pasar por referencia un objeto externo y asignarlo a los atributos de otro objetos (que es lo habitual), esos objetos quedan conectados.
Es decir, para construir una
Casa, primero he tenido que construir un
SalonCasa.
Son objetos distintos, pero
Casa incluye en su interior un
SalonCasa.
Entonces, si pasamos por referencia, los cambios que ocurran en el objeto externo
SalonCasa también quedarán reflejados en el atributo interno del objeto
CasaEsto se verá mucho mejor con un ejemplo.
Mira, aquí estoy creando un salon y una cocina.
Luego creo una casa y a su constructor les paso ese salon y cocina.
Y le pido a casa que muestre los valores de su nuevo salon y cocina (por cierto, a tu clase
Casa le faltan setters y getters para los atributos de Salon y Cocina)
Después de mostrarlos, modifico los valores del salon y de la cocina.
Y vuelvo a pedir a casa que muestre de nuevo sus valores de salon y cocina.
public class Prueba {
public static void main(String[] args) {
SalonCasa miSalon = new SalonCasa("Gigante", 10);
CocinaCasa miCocina = new CocinaCasa(true, 100);
Casa miCasa = new Casa(300, "Calle Paraiso", miSalon, miCocina);
System.out.println("Televisores: " + miCasa.getSalon().getNumeroDeTelevisores());
System.out.println("Fuegos: " + miCasa.getCocina().getNumeroDeFuegos());
//Cambiamos valores de miSalon y miCocina
miSalon.setNumeroDeTelevisores(3);
miCocina.setnumeroDeFuegos(4);
System.out.println("\n--Valores de salon y cocina cambiados --\n");
System.out.println("Televisores: " + miCasa.getSalon().getNumeroDeTelevisores());
System.out.println("Fuegos: " + miCasa.getCocina().getNumeroDeFuegos());
}
}
Resultado en pantalla:
Televisores: 10
Fuegos: 100
--Valores de salon y cocina cambiados --
Televisores: 3
Fuegos: 4
Fíjate que casa muestra el cambio de valores, a pesar de que en el objeto casa no hemos hecho cambios.
Los cambios los hemos hecho en los objetos salon y cocina, pero como casa tiene "referencias" a esos objetos, pues casa se verá afectada por esos cambios.
Ahora vamos a hacer exactamente el mismo ejercicio, pero usando el constructor que tú habías escrito.
Es decir, no vamos a pasar por "referencia", si no que de forma artificial vamos pasar por "valor".
¿Cuál será el resultado en pantalla?
Televisores: 10
Fuegos: 100
--Valores de salon y cocina cambiados --
Televisores: 10
Fuegos: 100
¡Oh!
El resultado es distinto. Esta vez los cambios que hemos hecho en cocina y salon, no han afectado al objeto casa.
Y esto es porque en tu constructor no asignabas la "referencia" recibida entre paréntesis, si no que construías objetos totalmente nuevos con los "valores" de esas "referencias".
Y vuelvo a preguntar, ¿esto es un problema?
Podría serlo.
Imagina que tenemos un objeto Alumno, que representa a "Juanito" y que vive en la calle "Las Flores".
Y tenemos una clase llamada Curso, donde tenemos insertados a 25 alumnos, entre ellos a "Juanito"
Supongamos que ahora "Juanito" se muda de domicilio y ahora vive en la calle "Las Cortes"
Si cambiamos este dato en el objeto que representa a "Juanito", y resulta que al objeto Curso lo habíamos pasado por "valor" y no por "referencia", tendremos el problema de que el "Juanito" que está dentro de Curso tiene el domicilio antiguo a diferencia del objeto "Juanito" que es externo a Curso.
Esto es un problema, en un sistema informático no podemos consentir esta discrepancia de datos.
Es que además "Juanito" puede estar insertado en múltiples objetos además de Curso. Puede estar insertado en un objeto que agrupe a los alumnos que hacen actividades extraescolares, otro objeto que agrupe alumnos que han solicitado beca, etc...
Cada vez que un alumno cambie de domicilio, no podemos ir rastreando todos los objetos donde ande insertado para cambiarle a todos ese dato.
Por eso es mejor pasar los objetos por "referencia", porque así haciendo un único cambio, este se verá reflejado en todos demás objetos donde pueda estar insertado.
Habrá ocasiones donde sí vamos a querer hacer una copia del "valor" un objeto para que no compartan "referencia" y sean objetos independientes.
Pero no es lo habitual.
Disculpa si me he extendido demasiado con explicaciones.
Pero no quería decirte simplemente "así no se hace, hazlo asá..."
Quería explicarte el motivo y es que además este es un tema que no es fácil de entender al principio.
El asunto de pasar datos por "valor o por "referencia" da para mucha literatura. Así que no te preocupes si aún no te ha quedado claro. Tampoco es algo que deba preocuparte mucho ahora mismo.
Simplemente recuerda que cuando recibas objetos en un constructor, salvo casos muy concretos, lo que vamos a hacer es asignar directamente esas referencias a los atributos.
public Casa(double valorSuperficie, String valorDireccion, SalonCasa objetoSalon, CocinaCasa objetoCocina){
superficie=valorSuperficie;
direccion=valorDireccion;
salon=objetoSalon;
cocina=objetoCocina;}