我正在学习JAVA,并遵循Herbert Shildt的《JAVA:The Complete Reference》一书。
我了解了Java中的抽象类,但是不明白这行背后的原因:
抽象类不能直接用new运算符实例化。
我搜索了web和stackoverflow,然后遵循以下问题:为什么我们不能在JAVA中实例化抽象类?而我们为什么不能实例化Java中的接口或抽象类没有匿名类的方法?
在一个答案中,有人写道:
简而言之,在一个好的面向对象程序中,您永远都不想实例化一个抽象类或接口。如果这样做,则设计可能是错误的。
我不明白为什么不实例化一个好的OOP
设计抽象类很重要。如果有人可以给出很好的解释,请提供帮助。
如果抽象类完全独立存在,那么它应该是没有意义的。
以车辆为例。您可以在不同时描述特定类型的车辆的情况下描述车辆吗?否-因为Vehicle只是描述一组相关对象的共同特征和行为的一种方式。或者,您可以将它们视为概念。
您的报价:
简而言之,在一个好的面向对象程序中,您永远都不想实例化一个抽象类或接口。如果这样做,则设计可能是错误的。
现场。如果您编写了一个抽象类,想要自己完全实例化,则它不是一个抽象类。如果您发现自己处在这种情况下,则可能需要执行另一个抽象级别,以将抽象部分与实际开始将类压缩为具体内容的位分开。您应该对抽象类所做的唯一一件事就是扩展它-将其转变为不太模糊的东西(如果您愿意,可以更具体一些)。
当然,Java有时似乎有点矛盾。实际上,为抽象类编写构造函数是完全有效的:
abstract class Vehicle {
// You might have some common variables defined here
Vehicle() { }
}
起初,这似乎有点愚蠢。当我不允许实例化类时,为什么要编写一个构造函数,该构造函数旨在实例化一个对象?如果您不编写默认构造函数,编译器甚至会为您创建一个默认构造函数!
答案是允许您实例化一个抽象类-只允许您直接使用new
关键字实例化它。但是抽象类的最重要的部分是它们被设计为可扩展的。
当实例化抽象类的子类时,可以super();
在构造函数内部显式或隐式调用:
public class Car extends Vehicle {
public Car() {
super(); // If you don't put this here, the compiler will!
}
}
这实际上是有道理的,当你想想看-你不能有车辆在它自己的,而是我的车是在停车场坐是肯定的车辆。Car
在这种情况下,一旦我对车辆的概念有了具体的扩展,就可以拥有车辆了。
这可能使您能够做的最有用的事情是创建通用集合。因为Vehicle是所有不同类型Vehicle的超类,所以我可以说:
List<Vehicle> vehicles = new ArrayList<>();
或者,如果您不想/不能使用菱形运算符(<>
):
List<Vehicle> vehicles = new ArrayList<Vehicle>();
这使我可以将任何类型的Vehicle放入该集合中:
vehicles.add(new Car());
vehicles.add(new Van());
vehicles.add(new Lorry());
vehicles.add(new Motorcycle());
// and so on...
尽管此方法还有许多其他优点,但在此答案中涵盖的内容太多了。
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句