访问子类对象的实例变量

 1 public class BaseTest {
 2 
 3     public static void main(String[] args)
 4     {
 5         new Derived(); // 1
 6     }
 7 }
 8 
 9 class  Base
10 {
11     private int i =2;
12     
13     public Base()
14     {
15         this.display();
16     }
17     public void display()
18     {
19         System.out.println("Base i is:"+i);
20     }
21 }
22 
23 class Derived extends Base
24 {
25     private int i =22;
26     public Derived()
27     {
28         i =222;
29     }
30     public void display()
31     {
32         System.out.println("Derived i is :"+i); //2
33     }
34     
35 }

运行结果:

  Derived i is :0

分析:new Derived();

系统会自动调用Base类中无参数的构造器来进行初始化。

构造器只是负责对Java对象实例变量执行初始化(也就是赋初始值),在执行构造器代码之前,该对象所占的内存已经被分配下来,这些内存里值都是默认值 0或者false,

或者null(引用类型的变量)。

当执行到1时,系统先为Derived对象分配内存空间,此时需要分配两块内存,用于存放Dericed对象的两个i实例变量,这两个i 一个属于Base定义的i实例变量,一个属于Derived定义的i实例变量。此时值都是0;

接下来在执行Derived类的构造器之前,先执行Base类的构造器。this.display();

这里的this代表谁?---当this在构造器中时,this代表正在初始化的java对象,此时的情况是:this位于Base()构造器中,但是这些代码实际在Derived()构造器内执行---是Derived()构造器隐式调用了Base()构造器的代码。此时 this.i 应该是2,this虽然代表Derived对象,但它却位于Base构造器中,它的编译时类型是Base,而它实际引用一个Derived对象。

当变量的编译时类型和运行时类型不同时,通过该变量访问它引用的对象的实例变量时,该实例变量的值由声明该变量的类型决定,但通过该变量调用它引用的对象的实例方法时,该方法行为将由它实际所引用的对象所决定。

因此在调用this.display()时,则实际变现出Derived对象的行为,即输出 Derived i is: 0.

程序创建一个子类对象时,系统不经会为该类中定义的实例变量分配内存,也会为其父类中定义的所有实例变量分配内存,及时子类定义了与父类中同名实例。

public class Apple extends Fruit {

    @Override
    public void info()
    {
        System.out.println("Apple方法");
    }
    public void AccessSuperInfo()
    {
        super.info();
    }
    
    public Fruit getSuper()
    {
        return super.getThis();
    }
    
    String color="红色";
    public static void main(String[] args)
    {
        Apple a =  new Apple();
        Fruit f = a.getSuper();
        System.out.println("a 和f 所引用的对象是否相同"+(a==f));
        System.out.println("访问a所引用的对象的color实例变量:"+a.color);
        System.out.println("访问f所引用的对象的color实例变量:"+f.color);
        a.info();
        f.info();
        a.AccessSuperInfo();
        
    }
}

class Fruit
{
    String color ="未确定颜色";
    public Fruit getThis()
    {
        return this;
    }
    public void info()
    {
        System.out.println("Fruit方法");
    }
}

运行结果:

a 和f 所引用的对象是否相同true
访问a所引用的对象的color实例变量:红色
访问f所引用的对象的color实例变量:未确定颜色
Apple方法
Apple方法
Fruit方法

原文地址:https://www.cnblogs.com/happinessqi/p/3439435.html