父类子类之间的一个经典题目(有关成员变量何时赋值和在哪里赋值的问题)

父类:

package cn.edu.lstc.extend;

public class Base {
	private String baseName = "base";

	public Base() {
//		baseName = "base";//默认成员变量在构造方法里这样赋值
		callName();
	}

	public void callName() {
		System.out.println(baseName);
	}
	/*
	 * static class Sub extends Base{ private String baseName = "sub"; public
	 * void callName(){ System.out.println(baseName); } public static void
	 * main(String[] args) { Base base = new Sub(); } }
	 */
}

子类:

package cn.edu.lstc.extend;

public class Sub extends Base {
    private String baseName = "sub";

    //下面注释的代码没写的话其实就是这样执行的
//    public Sub() {
//        super();
//        baseName="sub";
//    }
    public void callName() {
        System.out.println(baseName);
    }

    public static void main(String[] args) {
        Base base = new Sub();
    }
}

1. Base b = new Sub();

2. Base b = 直接忽略,从 new Sub();开始

3. 类加载器加载 Base,Sub 类到jvm;

4. 为Base,Sub 类中的两个属性baseName 分配存储空间,但是不初始化;

注意:属性的初始化时放在构造器中,按照代码顺序执行的。

5. new Sub会调用Sub的无参构造器,而在这个构造器中会隐式调用父类Base的无参构造器;

6. 父类Base的构造器中代码本质是

public Base()
{
baseName = "base";
callName();
}

即父类的属性baseName 的值为base。但为何输出null,骚年别急。

7. 因为父类构造器方法是在子类中调用的,即大环境是子类。此时,调用的方法callName()当然是指子类的方法。而这个方法打印的属性baseName当然也是子类的。那现在子类的属性baseName的值是多少呢?答案是null.因为此时子类Sub的构造器内代码本质是:

super();
baseName="sub";
此时baseName="sub"还没执行。

因此,左后的值当然是null.



猜你喜欢

转载自blog.csdn.net/u012110719/article/details/48950419
今日推荐