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对象列表,您知道它们都能够移动,但是对于调用者来说,特定动物的移动方式并不重要。