当我们创建一个扩展抽象类的子类对象时,抽象类构造函数也运行。但是我们知道我们不能创建抽象类的对象。那么是不是意味着即使构造函数无异常运行完毕,也不能保证对象是否被创建?
8 回答
那么是不是意味着即使构造函数无异常运行完毕,也不能保证对象是否被创建?
简单来说, aconstructor
不会创建对象。它只是初始化对象的状态。它是new
创建对象的操作员。现在,让我们稍微详细了解一下。
当您使用这样的语句创建对象时:
new MyClass();
对象首先由new
操作员创建。就在对新创建对象的引用作为结果返回之前,处理指示的构造函数以初始化新对象。
现在考虑Abstract class
and it's specific的情况SubClass
,当你这样做时:
AbstractClass obj = new ConcreteClass();
new
运算符创建 的对象ConcreteClass
,并调用其构造函数来初始化创建对象的状态。在这个过程中,也从构造函数中调用抽象类的ConcreteClass
构造函数,来初始化抽象类中对象的状态。
所以,基本上AbstractClass
没有创建对象。只是调用它的构造函数来初始化对象的状态。
得到教训:
对象是由
new
运算符创建的,而不是由构造函数本身的调用创建的。因此,在调用任何构造函数之前已经创建了对象。构造函数只是用来初始化创建的对象的状态。它本身不会创建对象。
对象状态也可以包含在抽象超类中。
- 所以,调用
Abstract class
构造函数的目的,只是为了完全初始化对象,过程中没有对象被创建。
看:
但是我们知道我们不能创建抽象类的对象
没错,但 JVM 可以。
是不是说即使构造函数无异常运行完毕,也不能保证对象是否被创建?
该对象肯定是在内部创建的。
调用构造函数是否意味着创建对象?
不总是。您可以使用调用构造函数super()
,this()
但它不会实例化对象。(但只会调用构造函数)
class AClass
{
AClass()
{
this(1); // will invoke constructor, but no object instatiated.
}
AClass(int a)
{
}
public static void main(String[] args)
{
AClass obj = new AClass(); // one object instantiated.
}
}
除非有任何例外,否则抽象类构造函数仅在子类的构造函数中运行(作为第一条语句)。因此,您可以确定每次运行构造函数时,它都处于创建对象的过程中。
也就是说,在创建单个对象的过程中,您可能会调用多个构造函数,例如通过Subclass()
调用调用Subclass(String)
哪个调用等等。AbstractClass
super()
Subclass == BaseClass + Extras you add in sub class
因此,当您通过调用其构造函数创建子类时,还会调用基类构造函数以确保(基类的)所有属性也正确初始化。
您只能将抽象类构造函数作为具体子类构造函数的一部分来调用。这没关系,因为抽象类被扩展为具体类,并且它是正在创建的具体类的对象。
当您调用子类的构造函数时,流程是这样工作的:
- 抽象类的构造函数运行 --> 对象在这里初始化了一半。
- 子类的构造函数完成执行 --> 对象已完全初始化,因此在此处完全创建。
当您使用 调用构造函数时new
,正在创建一个新对象。
现在,您可能已经知道,任何子类的每个构造函数,无论是隐式还是显式,直接或间接地调用父类的构造函数(反过来,它从自己的父类调用一个构造函数,一直到对象)。这称为构造函数链接。
但是,上述内容并不意味着创建了多个对象。该对象已在new
调用时创建,并且在该对象上工作的所有构造函数都已分配给一个分配区域。因此,构造函数链接不会创建新对象。一次调用new
将返回一个对象。
我完全不同意无法创建抽象类的对象,只有 jvm 才能在继承的情况下做到这一点,即使程序员有时也可以通过使用匿名类的概念在他/她打算这样做的任何时间或任何地方这样做: 看看这段代码,自己试试
abstract class Amit{
void hai()
{System.out.print("Just Wanna say Hai");}
abstract void hello();
}
class Main{
stic public void main(String[]amit)
{
Amit aa=new Amit(){
void hello(){Sstem.out.print("I actually dont say hello to everyone");
}};
aa.hello(); }}