2010-04-06 32 views
23

Duplicar posible:
Why is super.super.method(); not allowed in Java?Java ¿Cómo llamar al método de los abuelos?

Supongamos que tengo 3 clases A, B y C, cada una extendiéndose la anterior.

¿Cómo llamo al código en A.myMethod() desde C.myMethod() si B también implementa myMethod?

class A 
{ 
    public void myMethod() 
    { 
    // some stuff for A 
    } 
} 

class B extends A 
{ 
    public void myMethod() 
    { 
    // some stuff for B 
    //and than calling A stuff 
    super.myMethod(); 
    } 
} 

class C extends B 
{ 
    public void myMethod() 
    { 
    // some stuff for C 
    // i don't need stuff from b, but i need call stuff from A 
    // something like: super.super.myMethod(); ?? how to call A.myMethod(); ?? 
    } 
} 
+0

¿Por qué harías eso? ¿Puede dar un ejemplo? – Macarse

Respuesta

18

No puede. Esto es deliberado.

La clase B proporciona una interfaz (como en el concepto, no la palabra clave Java) para las subclases. Ha elegido no dar acceso directo a la funcionalidad de A.myMethod. Si necesita B para proporcionar esa funcionalidad, entonces use un método diferente para ella (nombre diferente, hágala protected). Sin embargo, es mejor "preferir la composición a la herencia".

+0

¡Gracias chicos! Intentaré retrabajar mi diseño. – Arkaha

+0

Arkaha, mira mi respuesta a tu pregunta. Es sintácticamente posible llamar a un método definido por una superclase que no es su antecesor inmediato (su * super *). Pero debes tener una razón válida para hacerlo. –

0

No estoy seguro de que pueda hacerlo. Java hace que todos los métodos sean virtuales por defecto. Esto significa que la solución más simple no funcionará: declare una variable de tipo A, asígnele su instancia C y llame al myMethod para llamar al C.myMethod.

Puede intentar reflejar el tipo A e invocar sus métodos directamente. Sería interesante ver qué sucede en este caso, pero me sorprendería que el envío virtual no se produjera ...

2

No puede y no debe.

Esto es un signo de mal diseño. Cambie el nombre de un método o incluya la funcionalidad común requerida en otro método o clase de utilidad.

+1

La reflexión * también * no proporciona una forma de hacer esto, las reglas normales del polimorfismo en tiempo de ejecución * todavía se aplicarán **. Ni siquiera puede implementar 'super.myMethod()' usando reflexión, y mucho menos el 'super.super.myMethod()' teórico. –

+0

correcto. actualizado. – Bozho

+0

No necesariamente, debe hacer eso cuando defina clases internas (por ejemplo, definir oyentes de acción en clases Swing o call back). Fuera de tales situaciones, sí, es un diseño incorrecto, pero * por sí mismo * no lo es. La sintaxis de Java lo admite de todos modos (ver mi respuesta a la pregunta de Arkaha). –

Cuestiones relacionadas