Java 为什么抽象类可以强制重写具体方法?

Java 为什么抽象类可以强制重写具体方法?,java,object,overriding,abstract-class,Java,Object,Overriding,Abstract Class,我使用一个库,其中抽象类用抽象方法重写从对象继承的具体方法: public abstract class A { @Override public abstract boolean equals(Object obj); } 为了扩展这个类,我必须实现equals方法: public class B extends A { @Override public boolean equals(Object obj) { return obj != nu

我使用一个库,其中抽象类用抽象方法重写从
对象继承的具体方法:

public abstract class A {
    @Override
    public abstract boolean equals(Object obj);
}
为了扩展这个类,我必须实现
equals
方法:

public class B extends A {
    @Override
    public boolean equals(Object obj) {
        return obj != null && obj.getClass() == B.class;
    }
}


为什么抽象方法(
A::equals
)可以覆盖具体方法(
Object::equals
)?我看不出这样做的目的。

在这个具体的例子中,它非常有意义。如果A的子类要在集合中使用,其中
equals
广泛用于定位对象,那么将
A
equals
方法抽象化将迫使您在
A
的任何子类中给出
equals
的非默认实现(而不是使用只比较实例引用的对象类的默认实现)

当然,您在B中建议的
equals
实现毫无意义。您应该比较2个B实例的属性,以确定它们是否相等

这是一个更合适的实现:

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);
    }
}

此外,当您重写
equals
时,请记住重写
hashCode
(因为
equals
hashCode
的契约要求,如果
a.equals(b)==true
,则
a.hashCode()==b.hashCode()
).

因为在这种情况下,您希望您的对象定义自己的
等于
,这可能与默认实现的行为不同


您不应将此视为删除功能,而应将其视为强制继承对象实现其自身的功能。

这将允许您强制子类重新实现方法。这是否是一个好主意是另一回事。您只会在希望强制执行比原始方法更强大的契约时才这样做提供。然后您应该仔细记录新合同。

这意味着您必须执行自己的
equals()
method

因为Java中的所有类都固有地扩展了该类。class
A
将继承
对象#equals
方法。假设您想在equals方法没有像这样显式实现时强制编译错误。在没有实现块的情况下抽象equals方法将使您能够这样做。

你很清楚,我真的认为这是在删除功能。@gontard:在这种情况下,你希望实现类规定它们自己的行为。要做到这一点,你需要确保默认实现不可访问,以便获得所需的行为。事实上,这并不容易。@OldCurmudgeon:i我希望没有人会意外地做这样的事情。这里正好相反-基类有一个抽象方法,而非抽象派生类有一个非抽象方法,它重写了基类方法。@Sharptoth我的问题不是很清楚。我说的是
a::equals
重写
Object::equals
我想你应该在问题中明确指出这一点。因为你只介绍了两门课,所以我确信这个问题只是关于他们的。@Sharptoth我编辑了我的问题
A
没有覆盖
B
equals()
,它是
B
重写
A
,并且是设计类时最常见的事情之一,因为它迫使您在
equals()
B
中实现,如果
B
没有其他属性(而且
A
),它就像一个
接口虽然与
B.class
B.class
实例相比,
B
的子类可能更正确。是的,也许
B
是一个单例