为什么实现接口的抽象类会错过接口方法之一的声明/实现?

2022-08-31 08:10:38

当你使用抽象类来实现接口时,Java中会发生一件奇怪的事情:接口的某些方法可能完全缺失(即既不存在抽象声明也不存在实际实现),但编译器不会抱怨。

例如,给定接口:

public interface IAnything {
  void m1();
  void m2();
  void m3();
}

下面的抽象类在没有警告或错误的情况下被愉快地编译:

public abstract class AbstractThing implements IAnything {
  public void m1() {}
  public void m3() {}
}

你能解释一下为什么吗?


答案 1

这是因为如果一个类是抽象的,那么根据定义,你需要创建它的子类来实例化。子类(编译器)将需要实现抽象类遗漏的任何接口方法。

按照您的示例代码,尝试在不实现该方法的情况下创建一个子类,并查看编译器给您带来了哪些错误。它将强制您实现此方法。AbstractThingm2


答案 2

完全没问题。
您无法实例化抽象类,但抽象类可用于容纳 m1() 和 m3() 的常见实现。
因此,如果每个实现的 m2() 实现不同,但 m1 和 m3 不是。你可以创建不同的具体 IAnything 实现,只需使用不同的 m2 实现,并从 AbstractThing 派生出来 - 遵循 DRY 原则。验证接口是否完全为抽象类实现是徒劳的。

更新:有趣的是,我发现C#将此强制执行为编译错误。在这种情况下,您将被迫复制方法签名,并在抽象基类中以“抽象公共”作为前缀。(每天都有新的东西:)