2012-07-21 9 views
5

Supongamos que tenemos una clase abstracta A y queremos obligar a todas las subclases a tener un campo determinado. Esto no es posible en Java, porque no podemos definir campos abstractos.¿Cómo evitar la falta de campos abstractos en Java?

Solución 1: Forzar subclases para implementar un método que proporcione el valor deseado.

abstract class A { 
    abstract int getA(); 
} 

Inconveniente: Cada subclase tiene que implementar un método para cada campo abstracto que queremos tener. Esto puede conducir a muchas implementaciones de métodos.

Ventaja: Podemos utilizar el método getA en la clase abstracta y aplicar métodos con él en A sin implementar en cada subclase. Pero el valor detrás del método no puede ser sobrescrito por la clase abstracta.

Solución 2: Simule el campo abstracto forzando a la subclase a dar un valor a la clase abstracta.

abstract class A { 
    int a; 

    public A(int a) { 
    this.a = a; 
    } 
} 

Inconveniente: Cuando tenemos varios campos (> 10), la llamada súper constructor se verá un poco feo y confuso.

Ventaja: Se puede utilizar el campo a en la clase abstracta y aplicar métodos con él en A sin implementar en cada subclase. Además, la clase abstracta puede sobrescribir el valor a.

Pregunta: ¿Qué solución alternativa es la forma común de alcanzar el objetivo? Tal vez hay uno mejor que los anteriores?

+2

¿Me falta algo? ¿Por qué no simplemente dar a la clase abstracta un campo * concreto * protegido? ¿Por qué el deseo de un campo "* abstracto *"? ¿Para qué es un campo abstracto para comenzar? Nuevamente, ¿qué estoy perdiendo o no entendiendo? ¿Estoy sobre simplificando tu problema? ¿Y qué problema de comportamiento (no de código) estás tratando de resolver de todos modos? –

+1

O puede proporcionar una implementación predeterminada de 'getA()' y simplemente anularla donde desee otro valor. – Keppil

+0

_¿Por qué quieres forzar a todas las subclases a tener un campo? El problema generalmente se formula mejor en términos de forzarlos a tener un comportamiento específico, lo cual se hace con las especificaciones del método. –

Respuesta

0

Creo que opt.1 es el limpiador con diferencia. Algunos getters y setters no son un gran problema, y ​​dudo que muchos casos de uso tengan más que unos pocos "campos" abstractos.

Acerca de opt.2, se olvida que los constructores no son heredados, y por lo tanto requeriría que todos los constructores de las subclases se implementen de manera que tengan en cuenta a.

1

Prefiero el primero. No me gusta juntar clases en el nombre de los archivos, cómo manejan el estado y cómo lo guardan. el primero es más cercano a open/close principal

Recomiendo evitar la herencia. la herencia es muy frágil y difícil de mantener. recuerde consejos efectivos de Java - prefiera la composición otra herencia

2

El método abstracto es probablemente el más orientado a objetos.

Si tiene demasiados campos, puede reagruparlos en un POJO (si es apropiado un nuevo concepto).

+1

buena característica es que a puede que ni siquiera exista: int getA() {return 4;} si la propiedad a siempre 4 para la subclase o getA() {return b + c;} si depende de otros campos. – josefx

+0

Haz que sea un método genérico y no solo posiblemente no exista, es posible que su tipo no exista. –

0

Solución 2 es muy común debido a 2 ventajas:

1) el que usted ha mencionado - el campo no pertenece a la subclase - pertenece a los padres y que es importante, ya que era "exigido" por el padre y porque el padre puede usarlo

2) Al subclasificar desde el padre, usted es muy consciente de este campo porque cuando implementa el constructor debe pasarlo. Si veo la primera solución no sabría qué entender de ella, de esta manera entiendo que la clase padre necesita este campo para funcionar, por lo que debe tener un valor significativo.

Nota: si tiene una clase que tiene 10 campos que deben inicializarse, es probable que algo esté mal en su diseño.

0

1. En realidad no es sobre lo que se quiere, pero su acerca de la flexibilidad y la capacidad de adaptarse a los cambios .

2. Siempre es mejor para Comportamientos de encapsulado que cambian constantemente, ya sea en una clase de interfaz o abstracta.

3. Usted primera Solución será bueno en los lugares donde se necesita implementación diferente para el mismo comportamiento en diferentes clases. Entonces, en este lugar, una interfaz o su primera solución alternativa será una buena opción.

Ej:

Considere Painting como una clase con paint() Método.

Ahora

paint() método puede tener estilos Acariciar, vuelo sin motor, etc sombreado de hacerlo.

Entonces es mejor encapsular ese método en una clase abstracta o una interfaz.

public interface Paint{ 

paintDoIt(String style); 

} 

4. Su segundo Wordaround será bueno en un lugar, donde desea ciertos comportamientos sean MUST implementado por la subclase.

Ej:

Considere coche como una clase abstracta, to be car Ahora es muy importante que debe tener una dirección , 4 ruedas, motor, etc. Así pues, estas características deben ser implementadas.

donde como otras funciones como el sistema de música, LCD, etc. son opcionales y dependen del tipo de automóvil.

Cuestiones relacionadas