继承】在继承中, 子类在实例化对象的时候 父类的构造方法必须初始化完成。是怎么理解?有未初始化完成的例子可以列举吗?

2021-05-28 20:24发布

3条回答

不是这个意思。所谓“实例化子类的对象前要先实例化父类中的内容,为父类初始化”,是指当子类正在实例化时,总是链式调用父类构造方法初始化父类空间。换句话说,子类的构造方法必须先调用父类的构造方法,完了才能干别的初始化工作。如果子类没有显式调用语句,编译器会隐式帮你加上。

如:

1
2
3
4
5
6
7
8
9
10
11
12
public class A
{
    public A()
    {
    }
}
public class extends A
{
    public B()
    {
    }
}

等价于:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
public class A
{
    public A()
    {
        super();//这里实际上是Object();
        //其他初始化工作
    }
}
public class extends A
{
    public B()
    {
        super();//这里实际上是A();
        //其他初始化工作
    }
}

另外,如果有这种情况:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
public class A
{
    X x=new X();
    public A()
    {
    }
}
public class extends A
{
    Y y=new Y();
    public B()
    {//这是类A空间里的字段都已经初始化完毕。
    }
}

在成员y被赋值之前,x一定已经存在。换句话说,X x=new X();一定先于Y y=new Y();执行。

追问

也就是说这句话只是对工作原理的一个描述。。。没有实际的语句能反映他的存在
A a = new B();     这个向上转型的操作,其实跟子类实例化之前必须先实例化父类的关系不大,对吗?

追答

它既是工作原理,也是语言特性或语言层面上的基本要求。它本身不是一个操作指令或语句。

A a = new B();

这个操作里当进行到赋值给A a时,实例化工作已经全部圆满结束,跟“跟子类实例化之前必须先实例化父类”没关系了。


一般来说,我们可以不用了解这句话也通常不影响我们的编程工作,但在某些特殊情况下可能会踩坑(我自己就踩过),应当注意。

比如:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
public abstract class A
{
    public A()
    {
        OnInit();
    }
    public abstract void OnInit();
}
public class extends
{
    X x=new X();
    @Override
    public void OnInit()
    {
        x.XXX();//Error!因为A构造方法会调用此方法,此时A的空间还没初始完毕,X x=new X();还没执行。于是x是个空引用。
    }
}

除此之外,代码中体现这个语言特性的机会很少。

或者说,要很直白的体现“子类实例化之前必须先实例化父类”除非把实例化的过程拖得很长,使得对象的实例化迟迟维持在半成品状态,这显然不是个好的设计。这意味着,如果非要“体现”,那通常这就是一个坑。


小橘子
3楼 · 2021-05-31 15:16
A为父类 B为子类

A a = new B();     //这个向上转型的操作,是不是就可以认为是 同时为父类和子类都初始化了呢?
                           //然后A中的对象a,B中的对象b是不是都可以直接使用了?

还是说在实例化子类的对象前要先实例化父类中的内容,为父类初始化~的意思是:
A a = new A();
B b = new B();

相关问题推荐

  • 回答 6

    eclipse 中类的继承创建有两种方式:1、手动敲代码通过 extends 关键字来继承public class A extends B {}2、在创建类的时候就选择好继承关系,点击 Finish,就自动创建好了继承关系

  • 回答 3

    在Java语言中,实现类的继承使用extends关键字格式如下:[public] class SubClass extends SuperClass{//类体的定义}

  • 回答 6

    1.java中是单继承的。每个子类只有一个父类。语法:子类 extends 父类2.在java中,即使没有声明父类,也有一个隐含的父类,就是Object类3.在子类中可以使用super来调用父类的方法4.继承中的构造方法问题在new一个子类实例的过程中,会优先自动调用父类默认的...

没有解决我的问题,去提问