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

时间:2022-09-25 12:27:57

It seems that every program that uses an abstract class could be rewritten without any abstract classes.

似乎每个使用抽象类的程序都可以在没有任何抽象类的情况下重写。

For example,

abstract class Animal {
  abstract int age();
}

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

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

If I have to implement age in the Dog and Cat classes, why define it abstract in the base class instead of providing a placeholder implementation:

如果我必须在Dog和Cat类中实现age,为什么要在基类中将其定义为abstract而不是提供占位符实现:

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

Are there any real world examples that show why abstract class is part of the language? Provide some examples to illustrate the concept.

是否有任何真实世界的例子说明为什么抽象类是语言的一部分?提供一些例子来说明这个概念。

2 个解决方案

#1


2  

Any class that can be instantiated should meet its contract so that all values meet their type contracts.

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

For example

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.

If Animal is abstract then this would produce a useful, compile-time error that tells the user that they need to instantiate a specific Animal subtype.

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

Abstract classes provide a way to define an interface without providing a complete implementation that meets a contract while providing a clear signal to those who are looking to construct an instance.

抽象类提供了一种定义接口的方法,无需提供满足合同的完整实现,同时向希望构造实例的人提供清晰的信号。

They provide a structure around which a full implementation can be fleshed out letting the author delegate the responsibility to complete the contract to authors of subtypes.

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

#2


1  

We don't need abstract classes, but they are useful in some cases (though sometimes overused - often interfaces are more appropriate in my opinion).

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

Your example with age() may not be the best one because calculating the age of a dog and the age of a cat will probably be the same, i.e. current date minus date of birth.

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

But consider this example: Say you have another abstract method move(destination) in your class Animal. Then the Fish class may implement this method by swimming, the Dog class by walking, the Frog class by jumping and the Bird class by flying.

但请考虑以下示例:假设您在类Animal中有另一个抽象方法move(destination)。然后Fish类可以通过游泳实现这种方法,通过步行实现Dog类,通过跳跃实现Frog类,通过飞行实现Bird类。

So if you have a list of Animal objects, you know they all are able to move, but it does not matter to the caller how a specific animal moves.

因此,如果您有一个Animal对象列表,您知道它们都能够移动,但是对于调用者来说,特定动物的移动方式并不重要。

#1


2  

Any class that can be instantiated should meet its contract so that all values meet their type contracts.

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

For example

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.

If Animal is abstract then this would produce a useful, compile-time error that tells the user that they need to instantiate a specific Animal subtype.

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

Abstract classes provide a way to define an interface without providing a complete implementation that meets a contract while providing a clear signal to those who are looking to construct an instance.

抽象类提供了一种定义接口的方法,无需提供满足合同的完整实现,同时向希望构造实例的人提供清晰的信号。

They provide a structure around which a full implementation can be fleshed out letting the author delegate the responsibility to complete the contract to authors of subtypes.

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

#2


1  

We don't need abstract classes, but they are useful in some cases (though sometimes overused - often interfaces are more appropriate in my opinion).

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

Your example with age() may not be the best one because calculating the age of a dog and the age of a cat will probably be the same, i.e. current date minus date of birth.

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

But consider this example: Say you have another abstract method move(destination) in your class Animal. Then the Fish class may implement this method by swimming, the Dog class by walking, the Frog class by jumping and the Bird class by flying.

但请考虑以下示例:假设您在类Animal中有另一个抽象方法move(destination)。然后Fish类可以通过游泳实现这种方法,通过步行实现Dog类,通过跳跃实现Frog类,通过飞行实现Bird类。

So if you have a list of Animal objects, you know they all are able to move, but it does not matter to the caller how a specific animal moves.

因此,如果您有一个Animal对象列表,您知道它们都能够移动,但是对于调用者来说,特定动物的移动方式并不重要。