为什么Java中不能使用new关键字来初始化抽象类?
我在某处读到我们无法初始化接口,例如:
interface MyInterface{};
下面的代码绝对是非法的:
MyInterface m = new MyInterface();
我记得我读过的文字是这样说的: 因为 new
关键字用于分配内存对于班级成员;所以对于接口来说,我们只有抽象函数,所以接口中没有什么可以分配的;因此,禁止初始化接口。
好吧,这对我来说很有意义。
但是对于抽象类,我们可以声明和定义抽象函数、非抽象函数以及普通变量;那么为什么我们也不允许初始化抽象类呢?正因为如此,我想知道抽象类中的变量(如果有的话)何时以及如何分配内存?
I have read somewhere that we cannot initialize an interface, for example:
interface MyInterface{};
And the following code is definitely illegal:
MyInterface m = new MyInterface();
And as I remember the text I have read said: that because the new
keyword is used to allocate memory for class members; so in case of interface, we only have abstract functions, so there is nothing to be allocated in an interface; therefore, initializing an interface is prohibited.
OK, that makes sense to me.
But in case of abstract class, we are allowed to declare and define abstract functions, non-abstract function, as well as normal variables;so why we also are not allowed to initialize an abstract class? And because of that, I was wondering when and how variables in an abstract class, if any, are allocated memory?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(10)
没有任何对象“只是”抽象类的实例 - 它始终是具体类的实例。否则,您可以调用抽象方法...并且不会调用任何实现。
抽象类中的变量的分配方式与任何其他类的变量分配方式相同,这些类恰好是正在初始化的实际类的超类 - 它们与来自其他类的变量一起生活。基本上,层次结构。
编辑:澄清一下,这是一种概念限制以及实现限制。抽象类通常包含抽象方法,这就是使其抽象的原因。抽象方法的要点是允许调用者在编译时检查该方法是否存在,即使抽象类不提供实现。 VM 通过防止“只是”抽象类的实例化来确保有一个实现。
现在,即使没有任何抽象方法,抽象类也可以用来防止实例化 - 基本上,抽象类的基本点是它不能实例化。直接实例化;只能实例化具体的子类。
No object is ever an instance of "just" an abstract class - it's always an instance of a concrete class. Otherwise you could call the abstract methods... and there'd be no implementation to be called.
The variables in an abstract class are allocated the same way as the variables of any other class which happens to be a superclass of the actual class being initialized - they live "with" the variables from the other classes in the hierarchy, basically.
EDIT: To clarify, this is a conceptual limitation as much as an implementation one. An abstract class usually contains abstract methods, which is the reason for making it abstract. The point of abstract methods is to allow the caller to have compile-time checking that the method will be there, even though the abstract class doesn't provide the implementation. The VM ensures that there is an implementation by preventing instantiation of "just" abstract classes.
Now abstract classes can also be used to prevent instantiation even if there aren't any abstract methods - basically the fundamental point of an abstract class is that it's one which can't be directly instantiated; only concrete subclasses can be instantiated.
当您说“初始化”时,您实际上指的是两个不同的事物:分配和构造。分配是为对象获取内存的过程;建造是将物体本身赋予生命的过程。
正如您所观察到的,您的接口类不需要内存。但这不是重点。抽象类无法构造,因为它是……嗯,抽象的。不存在抽象类型的对象。并且接口是抽象的。
将梅赛德斯视为一辆抽象汽车。你可以买一辆奔驰,但你不能买一辆抽象的汽车——它没有语义意义。您可以想象拥有的任何汽车都必须是混凝土类型的。
编辑:思考为什么一个类可能是抽象的可能会很有用:
因为它被声明为
抽象类
。这使得它通过法令完全抽象,没有给出任何理由。因为它具有抽象成员函数:成员函数未实现,并且具体的派生类必须提供实现。
因为它被声明为
interface
:这在道德上等价于“所有成员函数都是抽象的,并且不存在成员对象”。 (对此有一个单独的关键字允许接口规避单继承的限制。)When you say "initialize" you really mean two separate things: Allocation and construction. Allocation is the process of obtaining memory for the object; construction is the process of putting bringing the object itself to life.
As you observe rightly, your interface class requires no memory. But that's not the point. An abstract class cannot be constructed because it is... well, abstract. There is no object of abstract type. And interfaces are abstract.
Think of a Mercedes being an abstract Car. You can buy a Mercedes, but you cannot buy an abstract car - it doesn't make semantic sense. Any car you could conceivably have has to be of a concrete type.
Edit: It might be useful to contemplate why a class may be abstract:
Because it is declared
abstract class
. This makes it abstract flat-out by decree, no reason given.Because it has abstract member functions: The member function isn't implemented, and a concrete, derived class must provide the implementation.
Because it is declared
interface
: This is morally equivalent to "all member functions are abstract, and there are no member objects". (Having a separate keyword for this allows interfaces to circumvent the limitations of single inheritance.)这就是抽象类的要点:成为其他类的基类。它专门设计为不被实例化。
大多数抽象类都有抽象方法,但没有实现。如果实例化抽象类本身,您将如何调用这样的方法?
当您使用
new
创建抽象类的子类的新实例时,抽象基类所需的内存也会被分配。That's the point of an abstract class: to be the base class for other classes. It is specifically designed to not be instantiated.
Most abstract classes has abstract methods, which do not have implementations. How would you call such a method if you instantiated the abstract class itself?
When you use
new
to create a new instance of a subclass of an abstract class, the memory required for the base abstract class will be allocated then as well.抽象类是一个尚未完成的类,并且通常具有抽象成员(尽管不是强制性的)。所以你不能实例化抽象类。这是由语言定义的。
An abstract class is a class which is not finished yet and generally has abstract members(although it is not obligatory). So you cannot instantiate an abstract class. This is defined by the language.
http://download.oracle.com/javase/tutorial/java/IandI /abstract.html
http://download.oracle.com/javase/tutorial/java/IandI/abstract.html
抽象类不完整。他们有抽象方法,但没有实现。
如果您尝试调用其中之一会发生什么?
抽象类的变量由具体实例化类位于内存中。
abstract classes are not full. they have abstract methods, which are not implemented.
what will happen if you try to invoke one of them?
abstract class' variables are located on memory by the concrete instantiated class.
当在
扩展
抽象类的类上使用new
关键字时,会分配抽象类中的变量。因此,如果您没有扩展抽象类的类,则它们永远不会被分配。
The variables in an abstract class are allocated when the
new
keyword is used on a class thatextends
the abstract class.So if you don't have a class extending your abstract class they never get allocated.
当您实例化一个类时,您会为该类的多个方面分配内存,包括方法区域(它比这更复杂)。抽象类没有某些方法的定义,因此我们不能放置指向实际方法的指针。
抽象类包含(至少部分)没有定义的方法。您无法调用它们,因为没有代码可以运行。
When you instantiate a class, you're allocating memory for several aspects of the class, including an area for methods (it's significantly more involved than this). Abstract classes do not have definitions for some methods, so we cannot put pointers to actual methods.
Abstract classes contain -- at least partially -- methods without definitions. You can't call those, because there's no code to run.
也许带有一些代码的插图可能会有用。
所以这种行为一定要禁止。
Maybe an illustration with some code could be useful.
So this behavior must be forbidden.
顺便说一句,即使你的接口是空的,你也必须提供一个空的实现:
Serialized x = new Serialized(){};
抽象类也需要空花括号。但我无法想象会遇到对这些结构的需求。
By the way, even if your interface is empty, you would have to provide an empty implementation:
Serializable x = new Serializable(){};
The empty curly braces will be needed for an abstract class too. I can't think of encountering a need for these constructs though.