2011-01-15 10 views
10

En el ejemplo siguiente, ¿cómo puedo acceder, desde C, al método method() de la clase A?¿Cómo accedo a la súper-clase superior, en Java? [Mini ejemplo dentro]

class A { 
    public void method() { } 
} 

class B extends A{ 
    public void method() { } 
} 

class C extends B{ 
    public void method() { } 

    void test() { 
     method();   // C.method() 
     super.method(); // B.method() 
     C.super.method(); // B.method() 
     B.super.method(); // ERROR <- What I want to know 
    } 
} 

El error que estoy recibiendo es

Ningún caso encerrando del tipo B es accesible en su alcance

Respuesta: No, esto no es posible. Java no lo permite. Similar question.

+2

Consulte la respuesta de Jon Skeet a http: // stackoverflow.com/questions/586363/why-is-super-super-method-not-allowed-in-java – BoltClock

+0

Me sorprende que la pregunta no apareciera en las preguntas relacionadas, mientras la escribía. Mi respuesta está ahí. +1 –

Respuesta

17

No puede, y muy deliberadamente. Violaría la encapsulación. Que estaría faltando a lo B.method quiere hacer - posiblemente la validación de argumentos (suponiendo que hubiera alguna), invariantes hacer cumplir etc.

¿Cómo se podía esperar B para mantener una visión consistente de su mundo si cualquier clase derivada simplemente puede omitir lo comportamiento está definido?

Si el comportamiento B no es apropiado para C, no debería extenderlo. No intentes abusar de la herencia de esta manera.

+3

No se trata de si debería o no. Quería saber si es posible, eso es todo. Pero veo que no lo es. –

+5

No es tarea del idioma impedir que haga mi trabajo (trabajando en errores de otro código que no podemos solucionar). –

+7

@GlennMaynard: Entonces sugiero que cambies el lenguaje, tal vez a uno sin restricciones en absoluto ... no hay concepto de privado versus público, no hay noción de encapsulación. Cualquier restricción tendrá momentos en los que dificulta las cosas, pero el efecto general es positivo. –

1

No deberías.

Si desea acceder a los métodos en A, extienda desde A en lugar de B.

Cuando B se extiende a A, se supone que el objeto subyacente A no se manipulará de ninguna otra forma que no sea la forma en que lo hace. Por lo tanto, al acceder directamente a los métodos de A, podría estar rompiendo el funcionamiento de B.

Imagine, por ejemplo, que tiene una clase que implementa una lista, MyList. Ahora imagine que ampliamos esta lista con otra clase llamada MyCountingList, que anula los métodos add() y remove() para contar los elementos que se agregan/eliminan. Si omite el método add() que MyCountingList proporciona, utilizando el que tiene MyList, ahora ha roto la función de conteo de MyCountingList.

Así que, en resumen, simplemente no lo haga.

+0

Gracias por la explicación. Sé que C++ tiene soporte para esto; ¿Hay alguna razón por la cual Java no lo hace? – templatetypedef

+0

@templatetypedef: Estaría más interesado en saber por qué C++ * does * tiene soporte para algo que evidentemente viola la encapsulación. –

+0

Puntos válidos que hizo allí, pero su respuesta debería haber sido más fuerte. En realidad ** no puedes **, incluso si quisieras. Java no lo permite. –

2

Bueno, no hay una forma directa de hacerlo, pero siempre puede intentar soluciones.

No estoy seguro de la finalidad del método de acceso en la clase A de la clase C, pero siempre puede obtener ese método.

Usted podría crear una instancia de la clase A en la clase C y si eso parece demasiado simple, tratar de usar la API de reflexión ... [texto del enlace] [1]

Extreme Java

+0

Solo quería saber si era posible. Pero sí, crear una instancia de A también funcionaría. –

10

siguiente código podría sea ​​una solución alternativa (no es agradable, pero debería funcionar):

class A { 
    public void method() { } 
} 

class B extends A { 
    public void method() { } 
    protected void superMethod() { 
     super.method(); 
    } 
} 

class C extends B { 
    public void method() { } 

    void test() { 
     method();   // C.method() 
     super.method(); // B.method() 
     superMethod();  // A.method() 
    } 
} 
+0

Solo quería saber si era posible. Pero sí, eso sería una buena solución. –

Cuestiones relacionadas