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

为什么不能在Java中使用new关键字初始化抽象类?,java,interface,new-operator,abstract,Java,Interface,New Operator,Abstract,我在某个地方读到,我们无法初始化接口,例如: interface MyInterface{}; 以下代码绝对是非法的: MyInterface m = new MyInterface(); 我记得我读过的课文中说:因为new关键字用于为类成员分配内存;所以在接口的情况下,我们只有抽象的函数,所以在接口中没有要分配的东西;因此,禁止初始化接口 好吧,这对我来说很有意义 但对于抽象类,我们可以声明和定义抽象函数、非抽象函数以及正规变量;那么为什么我们也不允许初始化抽象类呢?正因为如此,我想知道抽

我在某个地方读到,我们无法初始化接口,例如:

interface MyInterface{};
以下代码绝对是非法的:

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

好吧,这对我来说很有意义


但对于抽象类,我们可以声明和定义抽象函数、非抽象函数以及正规变量;那么为什么我们也不允许初始化抽象类呢?正因为如此,我想知道抽象类中的变量(如果有的话)何时以及如何分配内存?

new
关键字用于
扩展
抽象类的类时,抽象类中的变量被分配


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

这就是抽象类的意义所在:成为其他类的基类。它是专门为不被实例化而设计的

大多数抽象类都有抽象方法,而这些方法没有实现。如果实例化抽象类本身,您将如何调用这样的方法

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

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

如果类包含抽象方法,则类本身必须 声明摘要


抽象类是一个尚未完成的类,通常有抽象成员(尽管不是强制性的)。因此不能实例化抽象类。这是由语言定义的。

抽象类未满。它们有抽象的方法,但没有实现。 如果您尝试调用其中一个,会发生什么


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

任何对象都不是“仅仅”抽象类的实例-它始终是具体类的实例。否则你可以调用抽象方法。。。而且也不会有需要调用的实现


抽象类中的变量的分配方式与任何其他类的变量相同,而其他类恰好是被初始化的实际类的超类——它们基本上与层次结构中其他类中的变量“共存”

编辑:澄清一下,这既是一个概念上的限制,也是一个实现上的限制。抽象类通常包含抽象方法,这就是使其抽象的原因。抽象方法的要点是允许调用方在编译时检查方法是否存在,即使抽象类不提供实现。VM通过防止实例化“just”抽象类来确保实现


现在,即使没有任何抽象方法,抽象类也可以用来防止实例化——基本上,抽象类的基本要点是它不能直接实例化;只有具体的子类可以被实例化。

当你实例化一个类时,你要为这个类的几个方面分配内存,包括一个用于方法的区域(比这个要复杂得多)。抽象类没有某些方法的定义,因此我们不能将指针放在实际方法上

抽象类包含——至少部分地——没有定义的方法。您不能调用它们,因为没有代码可运行。

当您说“初始化”时,实际上是指两个独立的东西:分配和构造。分配是为对象获取内存的过程;建筑是将物体本身赋予生命的过程

正如您正确观察到的,您的接口类不需要内存。但这不是重点。无法构造抽象类,因为它是。。。嗯,抽象的。没有抽象类型的对象。接口是抽象的

想象一辆奔驰是一辆抽象的汽车。你可以买一辆梅赛德斯,但你不能买一辆抽象的汽车——它没有语义上的意义。任何你可以想象的汽车都必须是混凝土的


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

  • 因为它被声明为
    抽象类
    。这使得它在没有给出任何理由的情况下,完全按照法令进行抽象

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

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


也许有一些代码的说明会有用

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

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

所以这种行为必须被禁止

顺便说一句,即使您的接口是空的,您也必须提供一个空的实现:

Serializable x=新的Serializable(){}


抽象类也需要空的花括号。不过,我想不出需要这些构造。

它们是在其子类调用super()@mre时分配的。如果他这样做,他就会明白它总是一个具体类的实例。@Kerrek SB-静态成员不属于任何实例。您可以这样称呼它们:
FileUtils.readFile(fileName)
例如。你不需要