在JAVA中实例化抽象类?

在JAVA中实例化抽象类?,java,class,oop,design-patterns,abstract-class,Java,Class,Oop,Design Patterns,Abstract Class,我正在学习JAVA并遵循这本书 我学习了Java中的抽象类,但无法理解这一行背后的原因: 抽象类不能使用新运算符直接实例化 我在网上和stackoverflow上搜索,然后问了以下问题:和 在一份答复中,有人写道: 简单地说,在一个好的面向对象程序中,您永远不应该希望 实例化抽象类或接口。如果你这样做了,设计就是 可能是错的 我不明白为什么不实例化一个抽象类对于良好的OOP设计很重要。如果有人能给出一个很好的解释,那么请帮助。你不能实例化一个抽象类,因为它通常包含抽象方法,而没有实现。为了实例化

我正在学习JAVA并遵循这本书

我学习了Java中的抽象类,但无法理解这一行背后的原因:

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

我在网上和stackoverflow上搜索,然后问了以下问题:和

在一份答复中,有人写道:

简单地说,在一个好的面向对象程序中,您永远不应该希望 实例化抽象类或接口。如果你这样做了,设计就是 可能是错的


我不明白为什么不实例化一个抽象类对于良好的
OOP
设计很重要。如果有人能给出一个很好的解释,那么请帮助。

你不能实例化一个抽象类,因为它通常包含抽象方法,而没有实现。为了实例化一个类,必须实现它的所有方法。子类将实现抽象方法,您将实例化这些子类

但是,即使实现了所有方法,如果希望阻止类的用户实例化该类,有时也会将该类定义为抽象类。如果类是子类,并且不包含创建完全功能对象所需的所有内容,则可以将其定义为抽象类


至于接口,它们只声明没有实现的方法(Java8中引入的默认方法除外),并且没有构造函数或类变量。如果不实现它们的所有方法,就无法实例化它们

抽象类旨在提供一个框架结构,因此它们中没有具体的实现


子类被期望填充到实现中,因此它们可以被实例化。

一开始可能看起来令人困惑,但您会习惯的

从技术上讲,它不能被实例化,因为-


它不包含方法定义。因此在实例化时浪费空间

理论上-


如果你能将抽象类实例化,它就违背了抽象类的全部目的1.当抽象类与普通类没有区别时,你就要费尽心机地创建这个概念。抽象类的唯一目的是扩展。抽象类将包含其所有子类的公共代码,子类将只实现与其相关的部分

抽象类对于命令模式非常有用。例如,假设您有一个任务需要执行一组操作,那么您可以定义一个命令抽象类:

public abstract class Command
  public void doCommand() {
    // Actual code here doing stuff...
    runInternal();
    // more code;
  }

  public abstract void runInternal();
}
现在的想法是,您可以实现一系列命令,例如:

public void RedCommand extends Command {
   public void runInternal() {
     // Real code that does red things
   }
}
…而且

public void BlueCommand extends Command {
   public void runInternal() {
     // Real code that does blue things
   }
}
现在,您可以有如下内容:

List<Command> list = new ArrayList<>();
list.add(new RedCommand())
list.add(new RedCommand())
list.add(new BlueCommand())

for(Command c : list) {
  c.doCommand();
}
List List=new ArrayList();
添加(新的RedCommand())
添加(新的RedCommand())
添加(新的BlueCommand())
for(命令c:list){
c、 doCommand();
}

现在很容易在以后添加更多命令,只需扩展命令抽象类并实现runInternal()方法。与所有事情一样,这种模式可能/被严重滥用,但在正确的环境中,它会使代码变得容易/可读。

您的答案在您给出的语句中:

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

您不应该希望实例化抽象类。因为抽象类是一个不完整的类,其实例化没有任何意义。您为类定义了一个行为,该行为将扩展abstract类。这更多的是关于一个人说“这些类应该是这样的,它们有共同点,所以请填空!”

当您需要一个类用于 继承和多态性,但是实例化 类本身,仅其子类当您 想要为一组共享某些属性的子类定义模板吗 通用实现代码,,但您还希望保证 无法创建超类的对象

因此,重要的是不要实例化抽象类因为根据正确的设计,抽象类的用途不同,当您要为一组子类定义模板时使用它,并且实例化类本身毫无意义


例如:假设您需要创建狗、猫、仓鼠和鱼对象。它们具有类似的属性,如颜色、大小、腿的数量以及行为,因此您可以创建一个动物超类。然而,动物是什么颜色的?一个动物物体有多少条腿?在这种情况下,实例化Animal类型的对象没有多大意义,而只是实例化其子类。

好吧,让我们举一个例子,以便您理解为什么在面向对象的范例中,抽象类不是用于实例化,而是用于扩展:

假设我们想要设计一个动物园应用程序,其中我们通过一组信息来展示每种动物,但每种类型都由它的类来展示,如果我们想遵循一个好的实践,那么我们创建一个名为
animal
的类,在这个类中我们放置关于所有动物的公共信息(id、price、entryDate…)

这将有助于从结构的角度设计其他类

public Lion extend Animal {
    private boolean isFromAfrica;
}

如果抽象类完全独立存在,那么它应该是没有意义的

以一辆汽车为例。您能否在不同时描述特定类型车辆的情况下描述车辆?否-因为车辆只是描述一组相关对象的共同特征和行为的一种方式。或者,您可以将它们视为概念

你的报价:

简单地说,在一个好的面向对象程序中,您永远不应该想实例化一个抽象类或接口。如果
public Lion extend Animal {
    private boolean isFromAfrica;
}
abstract class Vehicle {

    // You might have some common variables defined here

    Vehicle() { }
}
public class Car extends Vehicle {
    public Car() {
        super(); // If you don't put this here, the compiler will!
    }
}
List<Vehicle> vehicles = new ArrayList<>();
List<Vehicle> vehicles = new ArrayList<Vehicle>();
vehicles.add(new Car());
vehicles.add(new Van());
vehicles.add(new Lorry());
vehicles.add(new Motorcycle());
// and so on...