请允许我解释一下我的理解。
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?
答案 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的字段)。
举个例子 - 将以下代码中的P
从f()
更改为'package-local',并通过以下执行链private
见证NPE:
Derived#Derived() -> Base#Base() -> Derived#f() -> NPE!
答案 1 :(得分:2)
构造函数不会继承到子类。使用super()
,你可以调用超类构造函数。您无法从子类访问超类的私有变量/属性。此外,超类的私有成员也不会继承它的子类。
答案 2 :(得分:1)
构造函数不是在java中继承的。
子类继承所有成员(字段,方法和嵌套 来自其超类的类)。构造者不是成员,所以他们 不是由子类继承,而是超类的构造函数 可以从子类调用。
当您调用super()
时,您只需调用父构造函数,可以访问它所属类的私有成员。
至于问题的更新版本:
如上所述,super()
只是调用父构造函数。它不会在任何对象上调用,因为构造函数不是类的成员。
this
构造函数中的 P
将引用正在构造的子类(Q
)的实例。
修改强>
关于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);
}
}