Stratos: Punto de Encuentro de Desarrolladores

¡Bienvenido a Stratos!

Acceder

Foros





duda ambitos java

Iniciado por Güarmigue, 14 de Junio de 2007, 01:05:19 PM

« anterior - próximo »

Güarmigue

Hola, echándole una mano a un amigo para las oposiciones hemos encontrado un código que no nos cuadra nada:

tenemos la clase A:

public class A {

char c = 'A';

static void f(){
System.out.println("A");
}

void g(){
this.f();
}

}


La clase B:


public class B extends A{

char c = 'B';

static void f(){
System.out.println("B");
}

void h(){
System.out.println("PEPE");
}
}


Y la clase C con el main:

public class C {

public static void main(String[] args){
A a = new A();
B b = new B();
A c = b;

System.out.println(a.c);
System.out.println(b.c);
System.out.println(c.c);
}

}


Y resulta que la salida es:

A
B
A

Yo esperaba que la última A fuera una B ya que a c le estamos asignando un objeto ya creado de tipo B y b.c devuelve efectivamente una B. ¿Aluién sabe porqué, cuando se supone que b y c son el mismo objeto nos devuelven resultados distintos? ¿Porqué o cómo toma el char de la clase A y no se sobre-escribe con el char de la clase B si tienen el mismo nombre?

He estado probando y pese a que inicialice los dos char en el constructor me sigue dando el mismo resultado:
   char c = 'B';

public B() {
//super();
this.c = 'B';
}


solo obtengo el resultado que yo esperaba (A,B,B) cuando elimino el 'char c' de la clase B y hago el this.c en el constructor de B.

¿Alguien sabe explicarme esto? Gracias por adelantado :)
url=http://deadchannel.blogsome.com]Dead Channel[/url] - Blog de informática, juegos, tortugas y lo que me viene dando en gana ;P

shephiroth

CREO que el problema radica en que inicializas el valor del char c al declararlo. Declaralo solo sin inicializarlo (inicializalo en el constructor) y entonces te dara la salida A B B.

AgeR

Estoy espeso pero a verrrr

Haces A c = b;
Entonces c es una instancia de la clase A. b es una instancia de la clase B (que extiende la clase A). Como c "es del tipo" A, toma el valor que le daría a b si no estuviera "extendida".

Creo que no me acabo de explicar, pero bueno, por ahí andan los tiros creo yo.

Diferencial

Cita de: "Güarmigue"
public class C {

public static void main(String[] args){
A a = new A();
B b = new B();
ESTA LINEA ESTA MAL DEBERIA DE SER EN TODO CASO B c = b; si lo declaras como A te crea un objeto de tipo A y funciona porque B tiene la misma estructura que A, A c = b;

System.out.println(a.c);
System.out.println(b.c);
System.out.println(c.c);
}

}
PARA TENER COSAS QUE NUNCA HAS TENIDO, TENDRÁS QUE HACER COSAS QUE NUNCA HAS HECHO.

shephiroth

A ver señores, si B hereda de A, hacer A c = b; es CORRECTISIMO!!!!!!!!!!

Diferencial

Cita de: "shephiroth"A ver señores, si B hereda de A, hacer A c = b; es CORRECTISIMO!!!!!!!!!!

Cierto no me habia dado cuenta de que heredaba.
PARA TENER COSAS QUE NUNCA HAS TENIDO, TENDRÁS QUE HACER COSAS QUE NUNCA HAS HECHO.

Warchief

Cita de: "Güarmigue"
Y resulta que la salida es:

A
B
A

Yo esperaba que la última A fuera una B ya que a c le estamos asignando un objeto ya creado de tipo B y b.c devuelve efectivamente una B. ¿Aluién sabe porqué, cuando se supone que b y c son el mismo objeto nos devuelven resultados distintos? ¿Porqué o cómo toma el char de la clase A y no se sobre-escribe con el char de la clase B si tienen el mismo nombre?

¿Puede ser porque f es un método estático? Prueba a quitar "static".

Güarmigue

Cuantas respuestas! gracias a todos, pero aun no tenemos ganador...  :?

A ver, repaso las posibilidades que me habéis dado:

shephiroth: En el post comento que aun inicializando en el constructor sigue dando la misma salida, así que el problema no es que inicialice al declarar (aunque ya sabemos que no es lo más correcto)

Ager: eso tendría sentido si la variable fuera static, pero no lo es, por tanto ¿No debería la variable pertenecer al objeto y por tanto ser "machacada"?

Lo de diferencial ya lo respondisteis...

Warchief: f es static, y eso tiene que ver para otro ejercicio, pero 'char c' no lo es, no debería verse afectado en ninguna manera porque uno de los métodos lo sea... (sino vaya show no?)

¿Alguna idea más? Gracias de nuevo por las respuestas!
url=http://deadchannel.blogsome.com]Dead Channel[/url] - Blog de informática, juegos, tortugas y lo que me viene dando en gana ;P

sés

Si alguna vez haz heredado una clase y sobreescrito algún método y dentro haces esto para llamar al método de la clase padre, lo entenderás mejor:
void metodo() {
   super.metodo();  // llamar a metodo() en la clase padre
   // hacer algo
}



Me explico...

a tiene una variable c que vale 'A'.
b tiene una variable c que vale 'B'.

Si c es de tipo A, aunque se le asigne un objeto del tipo B, c.c hace referencia a la variable c dentro de a.

Realmente hay dos variables: la c dentro de B y la c dentro de A.
Haz un método dentro de la clase B que haga esto y llamalo:
System.out.println( "A.c="+super.c );  // variable en el padre
System.out.println( "B.c="+c );  // variable c en this


También puedes añadir a esos System.out esta:
System.out.println( ((B)c).c );


Espero haberme explicado bien... :S
Soy indeciso... ¿o no?

Güarmigue

Sés, gracias por la respuesta, aciertas en tus afirmaciones, había comprobado lo del super y el this dentro del constructor de B. También probé lo del casting y funcionaba,  pero la duda es:

¿Porqué al hacer c.c hago referencia a la variable c que se encuentra en A y no a la de B? ¿No es uno de los mecanismos de la herencia el sobrescribir los métodos y las variables?
url=http://deadchannel.blogsome.com]Dead Channel[/url] - Blog de informática, juegos, tortugas y lo que me viene dando en gana ;P

Warchief

LOL, ni caso a lo que puse de static, no había mirado que se hacía System.out.println, pensaba q se llamaba a f() ^^'

Warchief


lord_taran

Porque, al menos en Java, el polimorfismo vale para métodos, pero no para propiedades.
n saludo!
Lord Taran
Las Noyas de Taran

Güarmigue

CitarPorque, al menos en Java, el polimorfismo vale para métodos, pero no para propiedades.

Lord_taran, este no sería un caso de polimorfismo (el polimorfismo en una variable no tiene sentido como tal... el polimorfirmo es el que una función pueda admitir parámetros de diferentes tipos al estar implementada varias veces ¿no? Yo solo quiero que coja la variable más cercana en la cascada de ámbitos ;P) Sino de un tema de ámbitos, ¿porqué teniendo una variable en una subclase, que tiene el mismo nombre y tipo que otra de su superclase no la devuelve (y de hecho dentro de la clase cualquier operación que se refiera a la variable o incluso a this.c se efectúa sobre la variable de la subclase, el problema es al acceder directamente a la variable desde fuera de la clase)

Sé que es una tontería, y que de todas formas lo suyo es hacer el set y el get, que eclipse los genera solos y punto, pero ya me pica la curiosidad... Y además parece que no tiene una respuesta sencilla cuando nadie da con ella...
url=http://deadchannel.blogsome.com]Dead Channel[/url] - Blog de informática, juegos, tortugas y lo que me viene dando en gana ;P

lord_taran

Y, sin embargo, generalmente la gente suele esperar que siga el mismo principio que los métodos por lo que en los exámenes de certificación la respuesta que dan es la misma que yo he dado ;)
Por lo demás creo que con lo dicho con sés...
n saludo!
Lord Taran
Las Noyas de Taran






Stratos es un servicio gratuito, cuyos costes se cubren en parte con la publicidad.
Por favor, desactiva el bloqueador de anuncios en esta web para ayudar a que siga adelante.
Muchísimas gracias.