就像超类成员一样,超类构造函数是否构成子类对象状态的一部分?

时间:2015-03-26 21:18:38

标签: java oop inheritance nested subclass

请允许我解释一下我的理解。

class P
{
    P()
    {
        System.out.println("hi "+this); 
       /*which object of P is currently executing this constructor? 
         Is "this" here object referenced by q or some other object?*/
    }
}
class Q extends P
{
    Q()
    {
        super();  
        /*constructor of superclass called on this object(referenced by q) */
    }
}
class R
{
    public static void main(String args[])
    {
        Q q = new Q(); //constructor Q() invoked on object referenced by q
    }
}

所以我的怀疑是: 1.在P的哪个对象上调用super()(因为不存在)。 2. P()中的“this”是指什么?它和q是同一个对象吗?换句话说,这是= q?

3 个答案:

答案 0 :(得分:3)

包括ctors的代码没有定义'对象状态'。一组实例字段。而且,在底层,子类实例包括其超类的private个字段,但javac确保它们只能通过调用超类方法直接或间接访问(ctors)包括在内)。


关于您更新的问题:

class Q extends P
{
    Q()
    {
        super();  /*constructor of superclass called on this object(referenced by q) */
    }
}

这里Q延伸P,所以super()调用P的ctor。在执行P的ctor期间,this允许引用属于P的字段和方法以及它的超类型(例如,Object)w /访问修饰符强加的限制(我的意思是你只能访问{{ 1}}和w /限制public和'package-private'子类型成员),但不是P的子类型

关于“无法访问P的子类型”规则还有一个问题:如果你从P的ctor中调用一些非私有(可覆盖的)P方法,那么有一天这个方法可能会在protected或其他方面被覆盖子类型,你突然开始调用一些无法预料的代码!因此,Q内的this允许明确引用P的子类型方法,但不允许引用P的子类型字段(尽管可以通过P的子类型方法隐式地引用P的字段)。

举个例子 - 将以下代码中的Pf()更改为'package-local',并通过以下执行链private见证NPE:

Derived#Derived() -> Base#Base() -> Derived#f() -> NPE!

答案 1 :(得分:2)

构造函数不会继承到子类。使用super(),你可以调用超类构造函数。您无法从子类访问超类的私有变量/属性。此外,超类的私有成员也不会继承它的子类。

答案 2 :(得分:1)

构造函数不是在java中继承的。

根据official Java tutorial

  

子类继承所有成员(字段,方法和嵌套   来自其超类的类)。构造者不是成员,所以他们   不是由子类继承,而是超类的构造函数   可以从子类调用。

当您调用super()时,您只需调用父构造函数,可以访问它所属类的私有成员。

至于问题的更新版本:

  1. 如上所述,super()只是调用父构造函数。它不会在任何对象上调用,因为构造函数不是类的成员。

  2. this构造函数中的
  3. P将引用正在构造的子类(Q)的实例。

  4. 修改 关于2.通过在q方法中输出参考main,可以轻松验证这一点。它应该与System.out.println(this)构造函数中的P调用完全相同。

    public class R
    {
        public static void main(String args[])
        {
            Q q = new Q(); //constructor Q() invoked on object referenced by q
            System.out.println(q);
        }
    }