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

来源:互联网 发布:手机淘宝怎么看优惠券 编辑:程序博客网 时间:2024/04/30 13:12

父类:

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.



0 0
原创粉丝点击