为什么我们不能在JAVA中实例化一个抽象类?

时间:2014-02-10 15:24:33

标签: java oop inheritance constructor abstract-class

我理解:

  1. 由于抽象类本身没什么,即车辆,这就是为什么我们要创建像Car,Bike等具体实现的对象。
  2. 在对象链接期间调用Abstract类的构造函数。

  3. 我们永远不能直接创建Abstract类的对象,即使它包含一个构造函数并且所有方法都已实现

  4. 为什么? 我希望从编译器的角度理解为什么Java会强制这些?

    谢谢

16 个答案:

答案 0 :(得分:19)

抽象类不完整!作者将其标记为摘要,告诉您代码中缺少一些实现。作者完成了一些工作,但你必须自己填写一些内容以使其正常工作。 abstract关键字可确保没有人会意外启动此不完整的类。

想想修车。有人取下了刹车片,并准备在第二天更换刹车片。现在,为了防止有人意外驾驶这辆车(没有安装制动器),机械师在方向盘上安装了一把锁。这是一种自动防范措施。

答案 1 :(得分:11)

这不是技术限制,而是(正如您所指出的)逻辑限制。 Java(以及许多其他语言)强制执行各种规则并不是因为它们不可能破解,而是因为这是该语言的故意部分。

答案 2 :(得分:5)

“火箭男孩”显示了一些机械原因,但这是一个概念上的原因。

Abstract类表示抽象概念。以你的车辆为例。你不能建造一个不具体的车辆。你可以拥有一套车辆,可以用2004卡罗拉和'98福特护航以及1984 cs36(一种游艇),标志4萤火虫级中档散装运输(带稳定器的那种),你可以单独选择其中任何一个并将其称为车辆,但您不能拥有仅仅是车辆的东西,而不能拥有那些或其他特定类型的车辆。

抽象类表示诸如车辆之类的抽象概念。因此,实例化一个的想法是非感性的,因为要实际实例化它,你需要知道你要实例化的内容。

答案 3 :(得分:4)

  1. 如果一个类用关键字abstract标记,那么它被称为抽象类。它不能通过使用new运算符进行实例化。但是抽象类可以用作子类对象的超类引用

  2. 不是抽象类的类称为具体类

  3. Java API中有很多抽象类,其中大部分都包含在GUI库和集合框架中

  4. 必须扩展抽象类,并且必须覆盖抽象方法

  5. 如果使用关键字abstract声明方法,那么它不应该有body。只有它可以有名称,参数和返回类型,但不能有正文

  6. 如果你有一个抽象方法,那么这个类也必须被声明为abtracr,即具体类不能有抽象方法,只有抽象类可以有抽象方法

  7. 除抽象方法外,抽象类还可以包含实例成员,实例初始化器,构造函数,静态初始化器和静态成员。这里抽象类的构造函数和实例初始化程序将在实例化抽象类的子类时被调用,并且当抽象类将由JVM加载时将调用抽象类的静态初始化程序

  8. 如果具体类扩展了抽象类,那么它必须覆盖抽象超类的所有抽象方法,这称为抽象类的实现

  9. 对于抽象类的部分实现,我们可以采用一个可以扩展抽象超类的抽象子类。在这种情况下,子类覆盖抽象超类的所有抽象方法都是不必要的。抽象超类或接口的部分实现只能由抽象类完成。具体类不能用于抽象类的部分实现,因为具体类不能有抽象方法

  10. 抽象类和抽象方法不能用关键字final声明,即类可以是抽象的或类似的,类似于方法可以是最终的抽象

  11. 不能使用关键字private

  12. 声明抽象方法
  13. 不能使用关键字synchronized声明抽象方法。即使你需要一个Thread安全方法然后在抽象类的实现过程中(当抽象方法将被conrete子类覆盖时)被覆盖的方法可以用关键字synchronized标记

  14. 抽象方法不能用关键字static标记。因为静态方法不能被覆盖,所以只能通过子类静态方法隐藏它们

  15. 不能使用关键字native

  16. 标记抽象方法
  17. 不能使用关键字strictfp

  18. 标记抽象方法
  19. 所以只有你可以使用访问修饰符(除了私有),用抽象方法输入类型,参数

  20. conrete类不能有实例方法,但抽象类可以有抽象方法,静态成员,实例成员,静态初始化器,构造函数和实例初始化器

  21. 如果抽象类实现接口或扩展另一个抽象类,那么它必须覆盖接口的所有抽象方法。但这与具体类

  22. 不同
  23. 抽象类也可能没有任何抽象方法

  24. 使用new运算符无法实例化抽象类。因为摘要可能有抽象方法,即没有任何主体(或实现)的方法。因为对象不能有抽象方法而JVM不能分配抽象方法的内存

答案 4 :(得分:1)

因为抽象类是一个骨架结构(如果可能的话,是一个不完整的构造),因此称为抽象。

abstract class Person(){
   abstract void Speak();
}

意味着每个Person必须说话。这意味着每个人都应该知道如何说话(实施speak())。 new Person()不能拥有,所以不允许这样做。

答案 5 :(得分:1)

您无法实例化接口或抽象类,因为它会违反面向对象的模型。 Read more

答案 6 :(得分:1)

我的理解Abstract类可能包含abstract(没有实现的空)方法。如果我们实例化一个对象并调用空方法,它就不会起作用并可能导致问题,因此编译器会强制执行此规则。 任何进一步的打火机?

答案 7 :(得分:1)

抽象它自我告诉:存在于思想或作为一个想法,但没有物理或具体的存在。 在java术语中,抽象关键字定义,如果抽象出现在类名之前,则JDK告诉JVM关于丢弃该类对象的启动。 它是正确的,抽象类可以有多个构造函数,但仅用于构造函数链接。

答案 8 :(得分:0)

你无法实例化抽象类,因为它只是为你的类提供一个扩展它的结构。

如果您想要开始上课,那么为什么要将其定义为抽象

答案 9 :(得分:0)

因为Java限制了它为什么我们无法实例化抽象类。因为在一般情况下抽象意味着不完整所以我们不能制作不完整事物的对象。我们必须在具体类中提供抽象类的完整实现。但我们无法创建抽象类的对象。

答案 10 :(得分:0)

jvm播放限制我们实例化抽象类和接口的原因非常简单。

假设编译器允许我们实例化两个ok。

所以假设我的抽象类包含5个抽象方法,意味着只有方法原型没有方法体。

因此我们知道每个方法调用在jvm Java堆栈区域中创建一个单独的堆栈 内存分配基于方法结构发生 并且在执行该堆栈正在破坏之后。

因此,如果我的方法不包含任何正文,则意味着jvm如何预测内存以分配该方法

第二,如果没有主体意味着没有方法执行,那么它永远不会从你的Java堆栈区域中销毁,那么你可能会遇到内存输出错误。

因此,考虑这两种情况编译器限制我们实例化接口和抽象类

答案 11 :(得分:0)

因为抽象类是一个不完整的类(在某种意义上它不包含没有正文和输出的抽象方法),我们无法创建实例或对象;就像你说的界面一样。

答案 12 :(得分:0)

您可以实例化一个抽象类。您只需要提供一个具体的子类。

答案 13 :(得分:0)

在Java中,除少数情况外,所有内容都表示为一个对象。当您要实例化类(蓝图)时,必须知道类成员变量,成员方法和构造函数的确切大小。由于某些/所有方法都是抽象的,因此JVM不知道其大小。因此分配内存是没有用的。

但是,如果我们将内存分配部分从JVM中移走,并将此所有权分配给USER,我们可以实现一些解决此问题的方法。

答案 14 :(得分:-1)

实际上你可以 - 但是只有你实现任何已被声明为抽象或遗漏的方法。

/**
 * A classic adaptor pattern.
 *
 * @param <P>
 * @param <Q>
 */
public static interface Adapter<P, Q> {

  public Q adapt(P p);

}

/**
 * An I walks an iterator of one type but delivers items of a different type.
 *
 * Please fill in the `next()` method. Use an Adaptor for convenience.
 *
 * @param <S>
 * @param <T>
 */
public abstract static class I<S, T> implements Iterator<T> {

  protected final Iterator<S> it;

  public I(Iterator<S> it) {
    this.it = it;
  }

  @Override
  public boolean hasNext() {
    return it.hasNext();
  }

  @Override
  public void remove() {
    it.remove();
  }

}

/**
 * Use an adaptor to transform one type into another.
 *
 * @param <S>
 * @param <T>
 */
public static class IA<S, T> extends I<S, T> {

  private final Adapter<S, T> adaptor;

  public IA(Iterator<S> it, Adapter<S, T> adaptor) {
    super(it);
    this.adaptor = adaptor;
  }

  @Override
  public T next() {
    // Implement the abstract method on-the-fly.
    return adaptor.adapt(it.next());
  }

}

IA类实例化I抽象类的对象,并实现next类中缺少的I方法。实际上,您正在创建一个实现隐含抽象方法的匿名对象。

答案 15 :(得分:-1)

Java不允许实例化抽象类的原因是合乎逻辑的。我们还没有给出方法的定义,因此,如果它允许创建对象,则没有返回地址从堆栈中弹出函数,因此我们得到了卡住。因此,它的逻辑只是不允许对象instattion。