Chapter2、对象与内存控制(2)构造器显式调用、方法覆写、父类访问子类方法

1、一般的类的继承结构为
Object<--Parent<--Mid<--Sub 因此我们在new一个Sub类的时候,会先调用Mid的构造函数,而在Mid的构造函数中,会先调用Parent的构造函数,同样的,在Parent的构造函数中,会先调用Object的构造函数。 这些调用,可能是显式的调用,也可能是隐式的调用,这个都可以。 2、父类访问字类对象的实例变量 这一个问题,是我在看这本书的时候纠结了一会的问题,子类调用父类的时候,用起来都没有问题,那父类调用子类?是怎么个情况。书中有一个程序,我将其加了几行,更便于理解。

class Base{
	int i = 2;
	{
		System.out.println(“In static initialize Base”);
		i=1111;
	}
	public Base()
	{
		System.out.println(“In Construction function Base”);
		this.display();
		System.out.println(this.getClass());
	}
	public void display()
	{
		System.out.println(“i in Base “+i);
	}
}
class Derived extends Base{
	int i=22;
	{
		System.out.println(“In static initialize derived”);
		i=3333;
	}
	public Derived()
	{
		System.out.println(“In Construction function Derived”);
		i = 2;
	}
	public void display()
	{
		System.out.println(“i in Derived “+i);
	}
}
public class P32 
{
	public static void main(String[] args)
	{
		new Derived();
	}
}

到底应该输出什么?不好回答,看看结果,分析分析。

In static initialize Base
In Construction function Base
i in Derived 0
class Derived
In static initialize derived
In Construction function Derived

其实答案很明了的,正如前面所说,子类在初始化执行其构造函数的时候,会首先调用其父类的构造函数,因此就对于本例子来讲,Derived是Base的子类,main函数中,执行new Derived();调用了Derived的无参构造方法,此时会隐式调用父类的无参构造方法,即Base(),父类完成其初始化,因此此时,父类的i会初始化,调用非静态初始化方法、构造方法来初始化,而构造方法中调用了this.display();
那按理说应该打印的是这里面的1111呀?为什么不是?关键是此时的this指的是什么?我们用getClass()来看一下,一看,明白了,原来这里的this是子类,调用的方法也是子类的方法。而在子类中,此时的i并没有初始化,当然默认值就是0
有个疑问,这里是否可以理解成子类的display方法Override了父类的方法?这个需要再思考思考。
而此时,如果将

System.out.println("In Construction function Base");

改为

System.out.println("In Construction function Base"+iiii);

则会打印

In Construction function Base1111

与刚刚想的相同,如果将子类中的display方法注释掉,则运行结果如下

In static initialize Base
In Construction function Base1111
i in Base 1111
class Derived
In static initialize derived
In Construction function Derived

即Base类的构造方法中调用的display函数为Base的函数,这边的关键在于,如果子类中也包含display方法的时候,而此时的this是子类,因此此时调用的子类的方法,当子类中不存在该方法时,直接调用父类的方法。

About: happyhls


发表评论

电子邮件地址不会被公开。 必填项已用*标注