java - resueltos - para que sirve una clase abstracta
¿Por qué una clase abstracta puede forzar un método concreto para ser anulado? (5)
Utilizo una biblioteca en la que una clase abstracta anula un método concreto heredado de Object
con un método abstracto:
public abstract class A {
@Override
public abstract boolean equals(Object obj);
}
Para extender esta clase, tengo que implementar el método equals
:
public class B extends A {
@Override
public boolean equals(Object obj) {
return obj != null && obj.getClass() == B.class;
}
}
¿Por qué puede un método abstracto ( A::equals
) anular un método concreto ( Object::equals
)? No veo el objetivo de esto.
En este ejemplo específico tiene perfecto sentido. Si las subclases de A están destinadas a ser usadas en Colecciones, donde es equals
ampliamente utilizado para ubicar objetos, haciendo que el método de A
equals
obliga a dar una implementación de equals
a no predeterminada en cualquier subclase de A
(en lugar de utilizando la implementación predeterminada de la clase Object que solo compara referencias de instancia).
Por supuesto, su implementación sugerida de equals
en B tiene poco sentido. Debería estar comparando las propiedades de las instancias 2 B para determinar si son iguales.
Esta es una implementación más adecuada:
public class B extends A {
@Override
public boolean equals(Object obj) {
if (!(obj instanceof B))
return false;
B other = (B) obj;
return this.someProperty.equals(other.someProperty) && this.secondProperty.equals(other.secondProperty);
}
}
Además, recuerde anular el hashCode
cada vez que anule equals
(ya que el contrato de equals
y hashCode
requiere que si a.equals(b) == true
entonces a.hashCode() == b.hashCode()
).
Esto le permitiría forzar una subclase para volver a implementar un método. Si esta es una buena idea o no es otra cuestión. Solo haría esto si quisiera hacer cumplir un contrato más sólido que el método original provisto. A continuación, debe documentar cuidadosamente el nuevo contrato.
Porque en este caso, desearía que sus objetos definieran sus propios equals
, que supuestamente se comportarán de manera diferente a la implementación predeterminada.
No debe ver esto como una función de eliminación , sino más bien como hacer cumplir que los objetos heredados implementan los suyos.
Porque todas las clases en Java extienden inherentemente la clase Object . La clase A
heredará el método Object#equals
. Supongamos que desea forzar un error de compilación cuando el método equals no se implementa explícitamente como en este example . Hacer que el método equals sea abstracto sin un bloque de implementación le permitiría hacer esto.
Significa que debes implementar tu propio método equals()