为什么不能使用new关键字在Java中初始化抽象类?

时间:2011-09-07 14:11:19

标签: java interface new-operator abstract

我读过一些我们无法初始化界面的地方,例如:

interface MyInterface{};

以下代码绝对是非法的:

MyInterface m = new MyInterface();

我记得我读过的文字说:因为new关键字用于为类成员分配内存;所以在接口的情况下,我们只有抽象函数,所以在接口中没有任何东西可以分配;因此,禁止初始化接口。

好的,这对我来说很有意义。

但是在抽象类的情况下,我们可以声明和定义抽象函数,非抽象函数以及正常变量;那么为什么我们也不允许初始化抽象类?正因为如此,我想知道抽象类中的变量何时以及如何被分配内存?

10 个答案:

答案 0 :(得分:15)

没有对象是“只是”抽象类的实例 - 它始终是具体类的实例。否则你可以调用抽象方法......并且不会调用任何实现。

抽象类中的变量的分配方式与任何其他类的变量相同,后者恰好是正在初始化的实际类的超类 - 它们与“变量”中的变量一起生成层次结构中的其他类,基本上。

编辑:澄清一下,这是一个概念限制,与实现一样多。抽象类通常包含抽象方法,这是使其抽象化的原因。抽象方法的要点是允许调用者进行编译时检查,即使抽象类没有提供实现,该方法也会存在。 VM通过阻止“仅”抽象类的实例化来确保 实现。

现在抽象类也可以用于防止实例化,即使没有任何抽象方法 - 基本上抽象类的基本点是不能< / em>直接实例化;只能实例化具体的子类。

答案 1 :(得分:5)

当你说“初始化”时,你真的是指两个不同的东西:分配和构建。分配是获取对象内存的过程;建筑是将物体本身带入生活的过程。

正如您所看到的,您的接口类不需要内存。但那不是重点。抽象类不能构造,因为它是......好吧,抽象。抽象类型没有对象。接口是抽象的。

想想梅赛德斯是一辆抽象的汽车。你可以买一辆梅赛德斯,但是你不能买一辆抽象的汽车 - 它没有语义意义。你可以想象的任何一辆车都必须具体。


编辑:考虑为什么一个类可能是抽象的可能是有用的:

  • 因为它被声明为abstract class。这使得它通过法令抽象出来,没有给出理由。

  • 因为它有抽象的成员函数:成员函数没有实现,具体的派生类必须提供实现。

  • 因为它被声明为interface:这在道德上等同于“所有成员函数都是抽象的,并且没有成员对象”。 (对此有一个单独的关键字允许接口绕过单继承的限制。)

答案 2 :(得分:3)

这是抽象类的要点:成为其他类的基类。它专门设计为实例化。

大多数抽象类都有抽象方法,有实现。如果你实例化抽象类本身,你会如何调用这样的方法?

当您使用new创建抽象类的子类的新实例时,也会分配基本抽象类所需的内存。

答案 3 :(得分:3)

抽象类是尚未完成的类,并且通常具有抽象成员(尽管它不是强制性的)。所以你不能实例化一个抽象类。这是由语言定义的。

答案 4 :(得分:1)

  

抽象类是一个被声明为abstract的类 - 它可能也可能是   不包括抽象方法。 抽象类无法实例化,   但它们可以被分类。

     

如果一个类包含抽象方法,那么类本身必须是   宣布抽象。

http://download.oracle.com/javase/tutorial/java/IandI/abstract.html

答案 5 :(得分:1)

抽象类不完整。他们有抽象的方法,没有实现。 如果你试图调用其中一个会发生什么?

抽象类'变量由具体实例化类位于内存中。

答案 6 :(得分:0)

new关键字用于extends抽象类的类时,将分配抽象类中的变量。

因此,如果您没有扩展抽象类的类,那么它们永远不会被分配。

答案 7 :(得分:0)

当你实例化一个类时,你要为类的几个方面分配内存,包括方法的区域(它比这更重要)。抽象类没有某些方法的定义,所以我们不能把指针放到实际的方法上。

抽象类包含 - 至少部分 - 没有定义的方法。你不能打电话给那些,因为没有代码可以运行。

答案 8 :(得分:0)

也许包含一些代码的插图可能很有用。

abstract class AC{
    abstract public void m();
}

class Main{
    public static void main(String[] a){
        AC obj = new AC();
        obj.m();  /* Nothing to execute. */
    }
}

所以必须禁止这种行为。

答案 9 :(得分:0)

顺便说一下,即使你的界面是空的,你也必须提供一个空的实现:

Serializable x = new Serializable(){};

抽象类也需要空的大括号。我不能想到遇到这些结构的需要。