【问题标题】:Why can an abstract class force a concrete method to be overridden?为什么抽象类可以强制重写具体方法?
【发布时间】:2015-06-17 07:35:59
【问题描述】:

我使用一个库,其中抽象类用抽象方法覆盖从Object 继承的具体方法:

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)?我看不出这样做的目的。

【问题讨论】:

  • 这里正好相反——基类有一个抽象方法,非抽象派生类有一个覆盖基类方法的非抽象方法。
  • @sharptooth 我的问题不是很清楚。我说的是A::equals 覆盖Object::equals
  • 我想你应该在问题中明确表达。由于您只介绍了您的两门课程,因此我确定问题仅与它们有关。
  • @sharptooth 我已经编辑了我的问题
  • A 不是覆盖Bequals(),它是覆盖BA,这是设计类时最常见的事情之一,因为它迫使你在equals()B 中实现,就像interface

标签: java object overriding abstract-class


【解决方案1】:

在这个具体的例子中,它非常有意义。如果 A 的子类打算在 Collections 中使用,其中equals 被广泛用于定位对象,则使Aequals 方法抽象迫使您在任何情况下提供equals 的非默认实现A 的子类(而不是使用仅比较实例引用的 Object 类的默认实现)。

当然,您在 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(因为equalshashCode 的合同要求如果a.equals(b) == true 然后a.hashCode() == b.hashCode())。

【讨论】:

  • 如果 B 没有其他属性(A 也没有)使实例彼此不同,那么问题中的实现可能是明智的。虽然在考虑B 的子类时,与B.classthis.getClass() 实例比较会更正确。
  • 是的,也许B 是单身人士
【解决方案2】:

因为在这种情况下,您会希望您的对象定义自己的 equals,据推测其行为与默认实现不同。

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

【讨论】:

  • 你有眼光,我真的看到了这个作为删除功能
  • @gontard:在这种情况下,您想要实现类来规定它们自己的行为。为此,您需要确保默认实现不可访问,以便获得所需的行为。
  • 其实是is still accessable 但一点也不轻松。
  • @OldCurmudgeon:我希望没有人会意外地做这样的事情 XD
【解决方案3】:

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

【讨论】:

    【解决方案4】:

    这意味着你必须实现你自己的equals()方法

    【讨论】:

      【解决方案5】:

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

      【讨论】:

        猜你喜欢
        • 2017-09-26
        • 1970-01-01
        • 2012-05-05
        • 1970-01-01
        • 2012-11-29
        • 2015-04-24
        • 2019-11-19
        • 2023-01-27
        • 1970-01-01
        相关资源
        最近更新 更多