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中的所有类都固有地扩展了该类。classA
将继承对象#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
是一个单例