16

当我们创建一个扩展抽象类的子类对象时,抽象类构造函数也运行。但是我们知道我们不能创建抽象类的对象。那么是不是意味着即使构造函数无异常运行完毕,也不能保证对象是否被创建?

4

8 回答 8

21

那么是不是意味着即使构造函数无异常运行完毕,也不能保证对象是否被创建?

简单来说, aconstructor不会创建对象。它只是初始化对象的状态。它是new创建对象的操作员。现在,让我们稍微详细了解一下。

当您使用这样的语句创建对象时:

new MyClass();

对象首先由new操作员创建。就在对新创建对象的引用作为结果返回之前,处理指示的构造函数以初始化新对象。


现在考虑Abstract classand it's specific的情况SubClass,当你这样做时:

AbstractClass obj = new ConcreteClass();

new运算符创建 的对象ConcreteClass,并调用其构造函数来初始化创建对象的状态。在这个过程中,也从构造函数中调用抽象类的ConcreteClass构造函数,来初始化抽象类中对象的状态。

所以,基本上AbstractClass没有创建对象。只是调用它的构造函数来初始化对象的状态。

得到教训:

  • 对象是由new运算符创建的,而不是由构造函数本身的调用创建的。因此,在调用任何构造函数之前已经创建了对象。

  • 构造函数只是用来初始化创建的对象的状态。它本身不会创建对象。

  • 对象状态也可以包含在抽象超类中。

  • 所以,调用Abstract class构造函数的目的,只是为了完全初始化对象,过程中没有对象被创建。

看:

于 2013-01-22T07:14:25.270 回答
3

但是我们知道我们不能创建抽象类的对象

没错,但 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.
    }
}
于 2013-01-22T07:12:15.520 回答
2

除非有任何例外,否则抽象类构造函数仅在子类的构造函数中运行(作为第一条语句)。因此,您可以确定每次运行构造函数时,它都处于创建对象的过程中。

也就是说,在创建单个对象的过程中,您可能会调用多个构造函数,例如通过Subclass()调用调用Subclass(String)哪个调用等等。AbstractClasssuper()

于 2013-01-22T07:10:27.720 回答
2

Subclass == BaseClass + Extras you add in sub class

因此,当您通过调用其构造函数创建子类时,还会调用基类构造函数以确保(基类的)所有属性也正确初始化。

于 2013-01-22T07:13:17.797 回答
0

您只能将抽象类构造函数作为具体子类构造函数的一部分来调用。这没关系,因为抽象类被扩展为具体类,并且它是正在创建的具体类的对象。

于 2013-01-22T07:10:19.763 回答
0

当您调用子类的构造函数时,流程是这样工作的:

  1. 抽象类的构造函数运行 --> 对象在这里初始化了一半。
  2. 子类的构造函数完成执行 --> 对象已完全初始化,因此在此处完全创建。
于 2013-01-22T07:12:30.763 回答
0

当您使用 调用构造函数时new,正在创建一个新对象。

现在,您可能已经知道,任何子类的每个构造函数,无论是隐式还是显式,直接或间接地调用父类的构造函数(反过来,它从自己的父类调用一个构造函数,一直到对象)。这称为构造函数链接。

但是,上述内容并不意味着创建了多个对象。该对象已在new调用时创建,并且在该对象上工作的所有构造函数都已分配给一个分配区域。因此,构造函数链接不会创建新对象。一次调用new将返回一个对象。

于 2013-01-22T07:14:11.587 回答
0

我完全不同意无法创建抽象类的对象,只有 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(); }}
于 2013-12-05T11:16:00.090 回答