2009-01-06 39 views
10

Tengo la clase B, que hereda de la clase A. La superclase A es abstracta y contiene un método abstracto. No quiero implementar el método abstracto en la clase B, por lo tanto, también debo declarar que la clase B es abstracta. Declarando clase B abstracta, dos cosas me funcionan (los programas se compilan y ejecutan correctamente):Clases y métodos abstractos en Java, Herencia

1.) No declaro ningún método abstracto en la clase B, aunque la clase sea abstracta. Esto funciona, supongo, porque la clase hereda el método abstracto de la clase A, y esto es suficiente para que la clase se declare como abstracta: no necesitamos ningún otro método abstracto declarado directamente en la clase.

2.) Declaro el mismo método abstracto en la clase B como se declara en la clase A. Esto es una especie de anulación (?), No en el mismo sentido que la anulación en Java (usando el mismo encabezado, pero proporcionando una implementación diferente), aquí solo uso nuevamente el mismo encabezado del método.

Ambas cosas están funcionando, y no estoy seguro de si ambas están bien, y si algunas de ellas son preferidas (más correctas) que la otra. ¿Son las dos formas iguales (significan lo mismo para Java)?

Acá les dejo algunas clases de ejemplo, de modo que lo que quiero decir es más clara para usted:

Caso 1.):

public abstract class A { 
    public abstract String giveSum(); 
} 

public abstract class B extends A { 

} 

Caso 2.):

public abstract class A { 
    public abstract String giveSum(); 
} 

public abstract class B extends A { 
    public abstract String giveSum(); 
} 

Saludos

Respuesta

8

Son funcionalmente iguales, pero el primero es preferido porque es más corto y no es extraño.

+1

¿Qué tal "no confundir al lector acerca de si se está definiendo un nuevo método" en lugar de "no es raro"? ;-) –

+0

"is not strange" es más corto :-) –

2

Vaya con # 1. Reescribir la declaración de método en la clase secundaria es confuso. Y realmente no necesita ningún método abstracto en una clase abstracta, independientemente de si el padre es abstracto o no.

+0

Pero, ¿tiene sentido declarar una clase como abstracta, si no se declaran métodos abstractos en la clase (y la clase no hereda de una clase abstracta?) – user42155

+0

Ah, la publicación de Jared a continuación responde esta pregunta. – user42155

2

Entonces, la pregunta es: ¿Qué se prefiere cuando se subclasifica una clase abstracta en Java y no se quiere proporcionar la implementación?

a) marca subclase tan abstracto demasiado

b) marca subclase abstracta como también y volver a escribir la firma del método marcado como abstracto?

me inclinaría por la primera:

a) Marque subclase tan abstracto también.

El primero ya tiene la declaración de método abstracto, no tiene sentido repetirlo.

35

En Java, la anotación de clase abstract indica que no se puede crear una instancia directa de la clase. Una clase podría declararse abstract simplemente porque nunca debería crearse una instancia (quizás contenga solo métodos estáticos), o porque sus subclases deberían crearse una instancia en su lugar.

Es no un requisito que abstract clases contienen abstract métodos (la inversa es cierto: una clase que contiene uno o más abstract métodos deben ser abstract.)

La cuestión de si debe duplicar la la definición de método abstracto podría ser percibida como una pregunta de estilo, pero me resultaría difícil encontrar un argumento a favor de la duplicación de la definición (el único argumento que se me ocurre es en el caso en que la jerarquía de clases podría cambiar la semántica o el uso del método, y por lo tanto le gustaría proporcionar un javado adicional c en la clase B.)

El argumento principal contra la redefinición del método abstract es que el código duplicado es incorrecto: hace que la refactorización sea más engorrosa y más (se aplican todos los argumentos clásicos de "no duplicar código").

1

Tiene razón, los dos casos son equivalentes. Caso 1) es más simple, caso 2) es duplicación de código - evítelo. Pero puede haber una razón para hacerlo:

Si el método en la clase A no devuelve String pero supongamos que C, la clase B puede anularlo (desde Java 5) con un tipo de retorno más específico, digamos D (clase extiende C):

public abstract class A { 
    public abstract C giveSum(); 
} 

public abstract class B extends A { 
    public abstract D giveSum(); 
} 

public class C { 
    ... 
} 

public class D extends C { 
    ... 
} 
+0

http://en.wikipedia.org/wiki/Covariant_return_type. creo que solo implementado en java 1.5 (http://java.sun.com/developer/JDCTechTips/2004/tt1201.html#2) – Chii

Cuestiones relacionadas