2009-09-07 10 views
17

Refiriéndose here¿Puede un padre llamar a los métodos de la clase infantil?

A es una clase Java precompilado (también tengo el archivo de origen) B es una clase Java que estoy Autoría
B se extiende A.

¿Cómo puede ser implementada la lógica tal que A puede llamar a los métodos que B tiene.
Las siguientes son las condiciones:

  • no quiero tocar A (sólo como última opción sin embargo, que es si no existe otra solución ).
  • No quiero usar reflejo.

Como se indicó, si es necesario, podría modificar A. ¿Cuál podría ser la posible solución en ambos sentidos?

Respuesta

35

La clase A debe definir los métodos que va a llamar (probablemente como abstractos, y A debe ser una clase abstracta, según la excelente guide de Paul Haahr); B puede (de hecho para ser concreto DEBE, si el método es abstracto) anular esos métodos. Ahora, llamadas a esos métodos desde otros métodos en A, cuando suceden en una instancia de clase B, vaya a las anulaciones de B.

El patrón de diseño general se conoce como Template Method; los métodos a anular se denominan a menudo "métodos de enlace" y el método que realiza las llamadas, el "método de organización".

+0

@ Alex La clase A es una clase de biblioteca y no es abstracta. Para usar la biblioteca, extiendo A. ¿Qué hago en este caso? –

+0

@unknown, me alegro de que le haya gustado! -) –

+1

@Kevin, si se trata de una clase de biblioteca, entonces no puede saber con sensatez acerca de las clases de nivel de aplicación: ¡esa es la dirección incorrecta para una flecha de dependencia! Busque Inversión de Dependencia: cree una interfaz (está perfectamente bien depender de elementos abstractos como la interfaz) y haga que su clase de aplicación lo implemente, use la Inyección de Dependencia para suministrar la instancia de la clase de biblioteca con la implementación de la interfaz que necesita para realizar llamadas. Por cierto, si la biblioteca proporciona clases concretas y aún así requiere que las extienda, su diseño es dudoso: ¡envíe el ensayo de Haahr a los arquitectos de la biblioteca! -) –

1

Yo dudaría en hacer esto. Corrígeme si me equivoco y lo eliminaré, pero parece que quieres mantener un objeto A junto con un objeto B. Si de hecho no son el mismo objeto, la "vinculación" (ese es un término científico) que tendrás que hacer sería bastante feo.

+0

Lamento no haber entendido la pregunta, ¿podría volver a formularla, por favor? –

+1

@ kevin-Boyd por favor, examine el segundo comentario de Alex-Martelli a su respuesta (la larga). Él está señalando lo mismo que estaba tratando de decir. –

11

Sí, parece que si anula las funciones de super/base-classes, llama a esas funciones en la clase base irá a la clase secundaria/derivada. Parece un mal diseño en mi opinión, pero ahí lo tienes.

class Base 
{ 
    public void foo() 
    { 
     doStuff(); 
    } 
    public void doStuff() 
    { 
     print("base"); 
    } 
} 

class Derived extends Base 
{ 
    @Override 
    public void doStuff() 
    { 
     print("derived"); 
    } 
} 

new Derived().foo(); // Prints "derived". 

Obviamente todos los métodos Derived 's tienen que estar ya definido en Base, pero para hacerlo de otro modo (sin introspección) sería lógicamente imposible.

+6

Google ha implementado esta estructura exacta en AsyncTask con la clase Base como abstracto. No puedo entender cómo es su mal diseño – Diffy

+1

No puedo recordar mis pensamientos exactos, pero supongo que lamentaba el hecho de que todos los métodos en Java son virtuales por defecto. En C++ tienes que declarar que un método puede ser anulado en una clase derivada (mientras que en Java debes prevenirlo explícitamente con 'final'). Tal vez. – Timmmm

+0

* "Parece un mal diseño" *: me parece un comportamiento predeterminado sensato: normalmente anula un método porque * quiere * que se llame su versión principal. (No estoy seguro de si hay una forma para que la clase base llame explícitamente a su propio método en lugar de sobrescribir uno de una subclase). – nnnnnn

Cuestiones relacionadas