为什么不能在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)
例如。你不需要