为什么要在 java 语言中包含摘要 类?

Why include abstract classes in the java language?

似乎每个使用 abstract class 的程序都可以在没有任何 abstract classes 的情况下重写。

例如,

abstract class Animal {
  abstract int age();
}

class Dog extends Animal {
  @Override int age() { return ... }
}

class Cat extends Animal {
  @Override int age() { return ... }
}

如果我必须在 Dog 和 Cat classes 中实现 age,为什么在基础 class 中定义它 abstract 而不是提供占位符实现:

class Animal {
  int age() { throw new Error("override me"); }
}

是否有任何现实世界的例子可以说明为什么 abstract class 是该语言的一部分?提供一些例子来说明这个概念。

任何可以实例化的 class 都应该符合其约定,以便所有值都符合其类型约定。

例如

Animal a = new Animal();  // Would compile if Animal not abstract.
System.err.println(a.age());  // Use of a value that may not meet its contract.

如果 Animalabstract 那么这将产生一个有用的编译时错误,告诉用户他们需要实例化一个特定的 Animal 子类型。

摘要 classes 提供了一种定义接口的方法,而无需提供满足合同的完整实现,同时向那些希望构建实例的人提供明确的信号。

它们提供了一个结构,围绕该结构可以充实完整的实现,让作者将完成合同的责任委托给子类型的作者。

我们不需要抽象classes,但它们在某些情况下很有用(尽管有时被过度使用——在我看来,接口通常更合适)。

你的例子 age() 可能不是最好的例子,因为计算狗的年龄和猫的年龄可能是相同的,即当前日期减去出生日期。

但是请考虑这个例子:假设您在 class Animal 中有另一个抽象方法 move(destination)。那么Fishclass可以通过游泳实现,Dogclass可以通过步行实现,Frogclass可以通过跳跃实现,Bird class 飞行.

因此,如果您有 Animal 个对象的列表,您 知道 它们都可以移动,但这对调用者来说并不重要 如何特定动物移动。