Java - Java POO

 
Vista:
sin imagen de perfil

Java POO

Publicado por sergio (1 intervención) el 25/08/2021 03:33:00
Buenas a todos, estoy acostumbrado a programar en C++ por lo que hay cosas que en java se me escapa,
a la hora de diseñar un ejercicio de la facultad tengo el siguiente problema:
Como se puede observar en los archivos adjuntos he diseñado dos clase ,donde tengo el problema es a la hora de insertar objetos en el array productos que se encuentra en la clase Almacén , cuando intento insertar un segundo objeto este borra al primer objeto , es decir , el índice del array vuelve a 0 y no entiendo el por qué.

Muchas gracias por su atención.
Valora esta pregunta
Me gusta: Está pregunta es útil y esta claraNo me gusta: Está pregunta no esta clara o no es útil
0
Responder
Imágen de perfil de Kabuto
Val: 3.428
Oro
Ha mantenido su posición en Java (en relación al último mes)
Gráfica de Java

Java POO

Publicado por Kabuto (1044 intervenciones) el 25/08/2021 14:01:08
Hola.

No es correcto decir que Almacen hereda de Tprod.
1
public class Almacen extends Tprod

Cuando decimos que una clase hereda de otra, estamos diciendo que esta clase "es un... ".. lo que sea la otra clase.

Es decir, si yo digo que Empleado hereda de Persona
1
public class Empleado extends Persona
Entonces, estoy diciendo que un Empleado, es una Persona.

Eso es lógico.

Si digo:
1
public class Perro extends Animal
Entonces, estoy diciendo que un Perro, es un Animal.

Eso también es lógico.

Si digo:
1
public class Almacen extends Tprod
Entonces, estoy diciendo que un Almacen, es un Producto.

¿Eso es lógico? Para nada...

Un Almacen va a contener Productos en su interior, cierto, pero eso no significa que un Almacen sea un Producto.
Por tanto, no podemos hacer una relación de herencia entre estas dos clases. Ni falta que hace.
Así que el "extends Tprod" se lo puedes quitar a Almacen.
1
public class Almacen

Solo necesitamos que Almacen tenga como atributo un array de clase Tprod, pero no necesita heredar nada de ella.

Bien, esto era solo algo a mejorar. No tiene nada que ver con tu problema.


Tu problema viene por otro sitio.
Y lo que ocurre tiene que ver con el paso de objetos "por valor" o "por referencia".
En C++ puedes usar operadores para elegir uno u otro.

En Java no. En Java, cuando se pasa un objeto de clase, siempre es "por referencia".
¿Y como afecta esto a tu programa?
A ver si consigo hacerme entender, porque puede ser un poco difícil.

Mira, en el main() de ejecutable, has declarado un objeto Tprod para trabajar con él.
1
2
public static void main(String[] args) {
		Tprod p1=new Tprod();

Tu intención es usar ese objeto para recoger los valores que el usuario introduzca por teclado, modificar sus atributos, e insertarlo en distintas posiciones del array que tiene Almacen.
Aquí, modificar sus atributos con los setters, y lo envías para ser insertado:

1
2
3
4
5
6
7
8
9
10
11
12
case 'b':
				System.out.println("Inserte el nombre del producto");
				nombre=sc.next();
				p1.setNombre(nombre);
				System.out.println("Inserte el precio del producto");
				precio=sc.nextDouble();
				p1.setPrecio(precio);
				System.out.println("Inserte el stock del producto");
				stock=sc.nextInt();
				p1.set_stock(stock);
 
				dev=a.insertar(p1);

Pero, cuando tu envías ese objeto para ser insertado, tal y como he dicho antes, estás enviando una "referencia".
No estás enviando una copia del objeto (su valor) o un objeto nuevo.
Lo que envías, es una dirección de memoria que apunta al objeto p1.
Es decir, ahora mismo p1, tiene dos direcciones de memoria apuntándole:
- La instancia que has hecho en este método main() de Ejecutable
- Y lo que has insertado en el array de Almacén.

Insisto, no son dos objetos distintos. Son el mismo, pero con dos punteros.

¿Cuál es entonces el problema?
Pues que la segunda vez que en el menú pedimos "Insertar un producto", en tu código lo que haces es modificar los atributos de p1.
Pero los cambios que haces aquí, también quedan reflejados en la referencia que hay en el array de Almacen

Es decir, no estás creando un nuevo Tprod, estás modificando el que ya existe.
Por eso luego al insertar un segundo Tprod, no te lo permite.
No es que el nuevo sobreescriba al anterior (porque no hay nuevo). Lo que pasa es que has modificado el único que existe y al pedir insertarlo de nuevo, te dice que ya existe (claro, porque solo hay uno)

Mira, esta ejecución del programa.
Inserto un producto llamado "Pilas".
OK, no hay problema.

Luego intento insertar un producto llamado "Velas".
Pero no puedo.
Me dice que ya existe... y si le pido que me muestre la tabla, efectivamente salen las "Velas" y no las "Pilas".

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
***************MENU***************
********A.-Visualizar la tabla****
********B.-Insertar un producto***
********C.-Vender un producto*****
********D.-Vaciar el almacén******
********E.-Salir******************
Elige una opción
a
El almacén está vacío
***************MENU***************
********A.-Visualizar la tabla****
********B.-Insertar un producto***
********C.-Vender un producto*****
********D.-Vaciar el almacén******
********E.-Salir******************
Elige una opción
b
Inserte el nombre del producto
Pilas
Inserte el precio del producto
34
Inserte el stock del producto
11
1devuelve
El producto se ha insertado correctamente
***************MENU***************
********A.-Visualizar la tabla****
********B.-Insertar un producto***
********C.-Vender un producto*****
********D.-Vaciar el almacén******
********E.-Salir******************
Elige una opción
a
Nombre: Pilas
Precio: 34.0
Stock: 11
-----------------------
***************MENU***************
********A.-Visualizar la tabla****
********B.-Insertar un producto***
********C.-Vender un producto*****
********D.-Vaciar el almacén******
********E.-Salir******************
Elige una opción
b
Inserte el nombre del producto
Velas
Inserte el precio del producto
12
Inserte el stock del producto
11
El producto ya existe en el almacén
***************MENU***************
********A.-Visualizar la tabla****
********B.-Insertar un producto***
********C.-Vender un producto*****
********D.-Vaciar el almacén******
********E.-Salir******************
Elige una opción
a
Nombre: Velas
Precio: 12.0
Stock: 11
-----------------------
***************MENU***************
********A.-Visualizar la tabla****
********B.-Insertar un producto***
********C.-Vender un producto*****
********D.-Vaciar el almacén******
********E.-Salir******************
Elige una opción
e
Adios


¿Significa eso que las "Velas" se han insertado donde estaban las "Pilas"?
NO
Lo que ha pasado, es que para crear las "Velas", no hemos creado un objeto nuevo. Hemos modificado el que ya existía, que eran las "Pilas".

Resumiendo, tu programa no está creando varios productos. Solo trabaja con un único producto al que se le cambian el valor de sus atributos.

¿Cómo solucionarlo?
Por suerte, es mucho más sencillo solucionarlo, que explicarlo ja ja.

Te basta con hacer una nueva instancia para p1 cada vez que se vaya a insertar un nuevo producto
1
2
3
4
5
6
7
8
9
10
11
12
13
case 'b':
				p1 = new Tprod(); //Nueva instancia para p1
				System.out.println("Inserte el nombre del producto");
				nombre=sc.next();
				p1.setNombre(nombre);
				System.out.println("Inserte el precio del producto");
				precio=sc.nextDouble();
				p1.setPrecio(precio);
				System.out.println("Inserte el stock del producto");
				stock=sc.nextInt();
				p1.set_stock(stock);
 
				dev=a.insertar(p1);

Al hacer esto, la referencia p1, ahora apunta a un objeto completamente nuevo.
Siguiendo con el ejemplo de las "Pilas" y las "Velas"...,
Tras insertar las "Pilas" dijimos que tenemos dos referencias a ellas:
- p1
- La primera posición del array de Almacén

Pero ahora, al hacer nueva instancia con new Tprod(), las "Pilas" dejan de estar referenciadas por p1. Solo la primera posición del array apunta a ellas.
Ahora p1 apunta a un nuevo objeto, las "Velas" que vamos a insertar. Y al insertarlas, como ya no estamos modificando las "Pilas", no habrá problemas y se podrán insertar.


Perdona si me extendido mucho con la explicación, cuando la solución es tan simple.
Pero si no logramos entender cuál era la causa, te seguirá ocurriendo lo mismo en otros casos parecidos.

Si algo no ha quedado claro, vuelve a preguntar.

Un saludo.
Valora esta respuesta
Me gusta: Está respuesta es útil y esta claraNo me gusta: Está respuesta no esta clara o no es útil
0
Comentar