[SOLUCIONADO] Llamar métodos no estáticos/final desde constructores - JAVA

  • 6 Respuestas
  • 4496 Vistas

0 Usuarios y 1 Visitante están viendo este tema.

Desconectado phr4ckl0t

  • *
  • Underc0der
  • Mensajes: 23
  • Actividad:
    0%
  • Reputación 1
    • Ver Perfil
    • Email
Saludos muchachos, tiempo sin pasar por aquí espero estén bien.
El día de hoy me ha surgido una pregunta con base a una frase que he leido en un libro de "Como programar en Java 10ma edición" de Deitel y Deitel, donde argumentan que no se deben implementar metodos sobreescribibles en los constructores de clase, ya que se pueden generar resultados indeseados. El punto es que si tengo una superclase cuyo constructor utiliza un metodo de instancia para validar un atributo a la hora de inicializarlo, y sobreescribo ese metodo en la subclase, el constructor de la subclase hará la llamada al constructor de la superclase, el cual usará la version sobreescrita del metodo que implementa en su cuerpo, se me ha dado por probarlo pero los resultados no son los que esperaba, de seguro no me ha quedado clara la idea, no haciendo mas esto fué lo que probé.
Código: Java
  1. public class B{
  2.     private int a;
  3.  
  4.     public B(int a){
  5.         setA(a);
  6.     }
  7.  
  8.     public int getA(){
  9.         return a;
  10.     }
  11.  
  12.     public void setA(int a){
  13.         this.a = 0;
  14.     }
  15. }

Código: Java
  1. public class A extends B{
  2.  
  3.     private int a;
  4.  
  5.     public static void main(You are not allowed to view links. Register or Login[] args){
  6.         A a  = new A(5);
  7.         You are not allowed to view links. Register or Login.out.println(a.getA());
  8.     }
  9.  
  10.     public A(int a){
  11.         super(a);
  12.     }
  13.  
  14.     @Override
  15.     public void setA(int a){
  16.         this.a = 1;
  17.     }
  18. }

La idea era que al pasarle un argumento al constructor a la hora de instanciar a la clase A, este tomara la version sobreescrita del metodo setA() y me inicializara el atributo "a" con valor de 1, pero veo que está tomando la version de la superclase e inicializa el valor de "a" en 0, por lo que no se refleja lo que dice el libro, la verdad quiero saber como manejar esto para tener los conceptos claros, y digerir esta gota en el mar del conocimiento. Gracias de antemano.
« Última modificación: Agosto 23, 2017, 11:57:59 am por Gabriela »

Desconectado grep

  • *
  • Underc0der
  • Mensajes: 187
  • Actividad:
    0%
  • Reputación 4
    • Ver Perfil
    • Grep's personal site
You are not allowed to view links. Register or Login
...pero veo que está tomando la version de la superclase e inicializa el valor de "a" en 0, por lo que no se refleja lo que dice el libro...

Este resultado es correcto porque tienes dos private int a; diferentes (por ser privados, uno es solamente visible para la clase B y el otro es solamente visible para la clase A). Ya sea que llames a getA() desde una instancia de A o desde una instancia de B, getA() va a devolver el valor 0.

Dicho de otra forma:

Código: Java
  1. public class B{
  2. ...
  3. public B(int a){
  4.     setA(a);
  5. }
  6. ...
  7. }
  8.  

efectivamente llama a:

Código: Java
  1. public class A extends B {
  2. ...
  3.     @Override
  4.     public void setA(int a){
  5.         this.a = 1;
  6.     }
  7. ...
  8. }

el problema es que this.a = 1; asigna el valor a la variable privada de A, no a la variable privada de B.

Para que el prorgama funcione como esperas debes utilizar el keyword protected y declarar la variable solamente en la superclase.

CODIGO CORREGIDO:
Código: Java
  1. public class B{
  2.     // private int a;
  3.     protected int a;
  4.  
  5.     public B(int a){
  6.         setA(a);
  7.     }
  8.  
  9.     public int getA(){
  10.         return a;
  11.     }
  12.  
  13.     public void setA(int a){
  14.         this.a = 0;
  15.     }
  16. }
  17.  
Código: Java
  1. public class A extends B{
  2.     // private int a;
  3.  
  4.     public static void main(You are not allowed to view links. Register or Login[] args){
  5.         A a  = new A(5);
  6.         You are not allowed to view links. Register or Login.out.println(a.getA());
  7.     }
  8.  
  9.     public A(int a){
  10.         super(a);
  11.     }
  12.  
  13.     @Override
  14.     public void setA(int a){
  15.         this.a = 1;
  16.     }
  17. }
  18.  
Saludos
« Última modificación: Agosto 19, 2017, 09:14:48 pm por grep »

Desconectado phr4ckl0t

  • *
  • Underc0der
  • Mensajes: 23
  • Actividad:
    0%
  • Reputación 1
    • Ver Perfil
    • Email
Entonces basandome en tu aclaración, puedo decir que el problema me lo está generando el método getA(), ya que al ser "a" private el toma la variable private de B mas no la de A y por eso arroja el resultado especificado, para obtener el a = 1 entonces debo sobreescribir el método para que tome la variable private de A, o en su defecto declarar "a" como protected y solo en la superclase, aunque esto debilitaria el encapsulamiento, pero bueno el punto era entender el concepto y me lo has dejado bien en claro, mil gracias por tu tiempo y tu aporte  ;D ;D

Desconectado Hu3c0

  • *
  • Underc0der
  • Mensajes: 433
  • Actividad:
    0%
  • Reputación 0
  • In the middle Netbeans
    • Ver Perfil
La encapsulación es una forma de proteger contenido y es un concepto que hay que tener claro en programación ¿Cómo encapsulamos? pues con los modificadores de acceso.

Público (modificador public ), en cuyo caso la clase era visible a cualquier otra clase (cualquier otro
fragmento de código del programa).
Privada al paquete (sin modificador o modificador "por omisión"). En este caso, la clase sólo será
visible a las demás clases del mismo paquete, pero no al resto del código del programa (otros
paquetes).
En el caso de los miembros, disponías de otras dos posibilidades más de niveles de accesibilidad, teniendo
un total de cuatro opciones a la hora de definir el control de acceso al miembro:
Público (modificador public ), igual que en el caso global de la clase y con el mismo significado
(miembro visible desde cualquier parte del código).
Privado al paquete (sin modificador), también con el mismo significado que en el caso de la clase
(miembro visible sólo desde clases del mismo paquete, ni siquiera será visible desde una subclase
salvo si ésta está en el mismo paquete).
Privado (modificador private ), donde sólo la propia clase tiene acceso al miembro.
Protegido (modificador protected )

Para resumirtelo:
Si tú pones un atributo o método privado sólo puede ser accedido desde métodos de la misma clase
Si pones un atributo publico public puede ser accedido desde cualquier sitio dentro del package y fuera de él
Si pones un atributo protected sólo será accedido desde la propia clase y clase hijas o herederas

Lo que te están indicando  es que al hacer el método privado de la clase Padre no es accesible de la Clase Hija aunque herede de su padre para eso tendrían que ser atributos protected

Espero haberte aclarado el asunto Suerte y al Toro
You are not allowed to view links. Register or Login

Desconectado phr4ckl0t

  • *
  • Underc0der
  • Mensajes: 23
  • Actividad:
    0%
  • Reputación 1
    • Ver Perfil
    • Email
Claro que si Hu3c0, muchas gracias a ti también ya me queda resuelta la duda  ;D

Desconectado grep

  • *
  • Underc0der
  • Mensajes: 187
  • Actividad:
    0%
  • Reputación 4
    • Ver Perfil
    • Grep's personal site
You are not allowed to view links. Register or Login
...entonces debo sobreescribir el método para que tome la variable private de A, o en su defecto declarar "a" como protected y solo en la superclase, aunque esto debilitaria el encapsulamiento...

Ciertamente debilita el encapsulamiento. Una regla general en OOP (Object Oriented Programming) es hacer todo tan privado como sea posible. Vas a encontrar muy buenas respuestas en You are not allowed to view links. Register or Login pregunta hecha en StackOverflow.

La mejor alternativa es declarar la variable private int a; solamente en la superclase B y llamar al metodo setA() de la superclase B desde el metodo setA() de la subclase A.

Código: Java
  1. public class B{
  2.     private int a;
  3.  
  4.     public B(int a){
  5.         setA(a);
  6.     }
  7.  
  8.     public int getA(){
  9.         return a;
  10.     }
  11.  
  12.     public void setA(int a){
  13.         // this.a = 0;
  14.         this.a = a;
  15.     }
  16. }
  17.  

Código: Java
  1. public class A extends B{
  2.     // private int a;
  3.  
  4.     public static void main(You are not allowed to view links. Register or Login[] args){
  5.         A a  = new A(5);
  6.         You are not allowed to view links. Register or Login.out.println(a.getA());
  7.     }
  8.  
  9.     public A(int a){
  10.         super(a);
  11.     }
  12.  
  13.     @Override
  14.     public void setA(int a){
  15.         // this.a = 1;
  16.         super.setA(1);
  17.     }
  18. }
  19.  

Saludos

Desconectado phr4ckl0t

  • *
  • Underc0der
  • Mensajes: 23
  • Actividad:
    0%
  • Reputación 1
    • Ver Perfil
    • Email
Correcto mi estimado grep así mismo es, aunque ya ahí estaría demás hacer un @You are not allowed to view links. Register or Login ya que se puede trabajar directamente con el método heredado.
Muchas gracias por todo.

 

[SOLUCIONADO] ¿Kali Linux o Kali Linux Ligth ?

Iniciado por worq

Respuestas: 2
Vistas: 26446
Último mensaje Noviembre 21, 2017, 12:28:54 pm
por Codig0Bit
[SOLUCIONADO] ¿Como publicar un software como software libre?

Iniciado por FuriosoJack

Respuestas: 2
Vistas: 11767
Último mensaje Mayo 23, 2017, 07:24:22 am
por HATI
[SOLUCIONADO] Multiuploader de imagenes con mysql, hosting de imagenes con mysql

Iniciado por graphixx

Respuestas: 4
Vistas: 13957
Último mensaje Marzo 26, 2013, 05:42:58 pm
por Xt3mP
[SOLUCIONADO] Linux Mint, errores, errores y mas errores...

Iniciado por n1sendev

Respuestas: 12
Vistas: 17848
Último mensaje Noviembre 22, 2017, 06:50:55 am
por RuidosoBSD
[SOLUCIONADO] Ayuda urgente con Virus "Virus.Win32Sality"

Iniciado por Napsters

Respuestas: 6
Vistas: 16546
Último mensaje Junio 11, 2012, 03:38:18 am
por Satyricon