在JAVA中实例化一个抽象类? [英] instantiating an abstract class in JAVA?

查看:130
本文介绍了在JAVA中实例化一个抽象类?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在学习JAVA并遵循本书 JAVA:Herbert Shildt的完整参考文献



我在Java中学到了抽象类,但是无法理解这行后面的原因:


抽象类不能使用new运算符直接实例化。


我通过网络和stackoverflow进行了搜索,并遵循了以下问题:为什么我们不能在JAVA中实例化抽象类? p>

在一个答案中,有人写成:


程序,你应该永远不想
实例化一个抽象类或接口。如果你这样做,设计是
可能是错误的。


我不明白为什么重要不要实例化抽象class for good OOP 设计。

抽象类应该是不是有意义



以车辆为例。你能描述一辆没有同时描述特定类型的车辆的车辆吗?否 - 因为Vehicle只是描述一组相关对象的常见特征和行为的一种方式。



您的报价:

您可以将它们视为

简单来说,在一个好的面向对象的程序中,你不应该想要实例化一个抽象类或接口。如果你这样做,那么设计可能是错误的。


如果您编写了一个您希望完全实例化的抽象类,则不是抽象类。如果你发现自己在这种情况下,你可能需要执行另一个层次的抽象,以将抽象部分与真正开始将类压缩为具体的部分分离。你应该用一个抽象类来做的唯一的事情是 extend - 把它变成更加模糊的东西(或者更具体的如果你喜欢)。



当然,Java看起来有点矛盾。事实上,为抽象类编写构造函数是完全有效的

  b 
$ b //你可能有一些常见的变量定义在这里

Vehicle(){}
}

起初这似乎有点蠢。为什么我可以写一个构造函数,这是为了允许你实例化一个对象,当我不允许实例化类?如果你不写一个,编译器甚至会为你创建一个默认的构造函数。



答案是你 允许实例化一个抽象类 - 您不能直接使用 new 关键字直接实例化它。但是抽象类的最重要的部分是它们被设计为扩展



当你实例化一个抽象类的子类时,您可以在构造函数中显式或隐式调用 super();

  public class Car extends Vehicle {
public Car(){
super(); //如果你不把这里,编译器会!
}
}

不能有自己的车辆,但我的汽车坐在停车场 车辆。一旦我有一个具体的扩展到我的概念的车辆, Car 在这种情况下,然后我可以有一个车辆



这使你能做的最有用的事情是创建通用集合。因为车辆是所有不同类型的车辆的超类,我可以说:

  List< Vehicle> vehicles = new ArrayList<>(); 

或者如果您不想/不能使用菱形运算符( <> ):

  vehicles = new ArrayList< Vehicle>(); 

这允许我将任何类型的车辆放入该集合:

  vehicles.add(new Car()); 
vehicles.add(new Van());
vehicles.add(new Lorry());
vehicles.add(new Motorcycle());
//等等...

虽然还有很多其他优点,太多无法覆盖在这个答案。


I am learning JAVA and following the book JAVA:The Complete Reference by Herbert Shildt.

I learned about abstract classes in Java, but could not understand reason behind this line:

An abstract class cannot be directly instantiated with new operator.

I searched over web and stackoverflow and followed these questions: Why can't we instantiate a abstract class in JAVA? and I know, we can not instantiate either an interface or an abstract class in java except using anonymous class method but what is the reason behind it?

In one answer, someone wrote as:

Simply, in a good object oriented program, you should never want to instantiate an abstract class or interface. If you do, the design is probably wrong.

I do not understand why it is important not to instantiate an abstract class for good OOP design. If someone can give a good explanation, then please help.

解决方案

An abstract class should be something that doesn't make sense if it exists completely on its own.

Take a Vehicle for example. Can you describe a Vehicle without describing a specific type of Vehicle at the same time? No - because Vehicle is just a way of describing common features and behaviours of a group of related objects. Alternatively, you could think of them as concepts.

Your quote:

Simply, in a good object oriented program, you should never want to instantiate an abstract class or interface. If you do, the design is probably wrong.

Is spot on. If you've written an abstract class that you want to instantiate completely on its own, then it isn't an abstract class. If you ever find yourself in this situation, you probably need to carry out another level of abstraction to separate out the abstract parts from the bits that actually start to condense the class into something concrete. The only thing you should want to do with an abstract class is to extend it - to turn it into something less vague (or more concrete if you prefer).

Of course, Java can seem a little contradictory at times. In fact, writing a constructor for an abstract class is perfectly valid:

abstract class Vehicle {

    // You might have some common variables defined here

    Vehicle() { }
}

At first this seems a little stupid. Why can I write a constructor, which is designed to allow you to instantiate an object, when I'm not allowed to instantiate the class? The compiler will even create a default constructor for you if you don't write one!

The answer there is that you are allowed to instantiate an abstract class - you're just not allowed to instantiate it directly using the new keyword. But the most important part of abstract classes is that they're designed to be extended.

When you instantiate a subclass of an abstract class, you either explicitly or implicitly call super(); inside the constructor:

public class Car extends Vehicle {
    public Car() {
        super(); // If you don't put this here, the compiler will!
    }
}

This actually makes sense when you think about it - you can't have a Vehicle on it's own, but my car that's sat in the car park is definitely a Vehicle. Once I have a concrete extension to my concept of a Vehicle, Car in this case, then I can have a Vehicle.

Probably the most useful thing that this enables you to do is create generic collections. Because Vehicle is the superclass of all of the different types of Vehicle, I can say:

List<Vehicle> vehicles = new ArrayList<>();

Or if you prefer not to/can't use the diamond operator (<>):

List<Vehicle> vehicles = new ArrayList<Vehicle>();

This allows me to put any type of Vehicle into that collection:

vehicles.add(new Car());
vehicles.add(new Van());
vehicles.add(new Lorry());
vehicles.add(new Motorcycle());
// and so on...

Although there are many other advantages to this, too numerous to cover in this answer.

这篇关于在JAVA中实例化一个抽象类?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆