Java 构造器之访问子类对象的实例变量


内容参考《疯狂Java程序员的基本修养》李刚 著

一、情况描述

子类的方法可以访问父类的实例变量,是因为子类继承父类会获得父类的成员变量和方法;
但父类的方法不能访问子类的实例变量,因为子类不知道它将被哪个子类继承;
但在极端情况下,可能出现父类访问子类变量的情况。

代码说明:
Base 类:

package com.tide.test;

/**
 * Created by wengliemiao on 16/3/31.
 */
public class Base {
    private int i = 2;

    public Base() {
        System.out.println("Base 无参构造器");
        this.display();
    }

    public void display() {
        System.out.println("Base display: " + i);
    }
}

Derived 类:

package com.tide.test;

/**
 * Created by wengliemiao on 16/3/31.
 */
public class Derived extends Base {
    private int i = 22;

    public Derived() {
        System.out.println("Derived 无参构造器");
        i = 222;
    }

    public void display() {
        System.out.println("Derived display: " + i);
    }

    public static void main(String[] args) {
        new Derived(); // (1)
    }
}

输出结果:
例1

说明:
1. Java 对象不是由构造器创建的,构造器只是负责对Java对象实例变量执行初始化。即在构造器之前,该对象所占的内存已经被分配出来了,且内存中的值默认为空值(基本类型变量默认为0或false,引用类型变量默认为null);
2. 当程序调用(1)处代码时,系统会先为Derived对象分配内存空间。此时系统内存为Derived对象分配两块内存:Derived 类定义的变量 i 和 Base 类定义的变量 i。

二、分析

由于定义变量时的初始化顺序在构造器初始化之前(参看:Java变量的初始化时机),因此Base 类构造器相当于:

public Base() {
    i = 2;
    this.display();
}

输出 i 的值:

public Base() {
    System.out.println("Base 无参构造器, i = " + this.i);
    this.display();
}

输出为:
说明2

此处 this 代表谁?

当 this 在构造器中时,this 代表正在初始化的Java对象。从代码中可看出 Derived 类的构造器隐式调用了 Base 类的构造器,因此 this 是 Derived 对象。为Derived类增加一个 sub() 方法。

代码验证如下:

 public Base() {
    System.out.println("Base 无参构造器, i = " + this.i);
    System.out.println(this.getClass());
    this.display();
    // this.sub(); // this 的编译时类型是 Base,因此不能调用sub() 方法
}

输出结果为:
说明3

输出 class com.tide.test.Derived 说明 this 引用代表的是 Derived 对象;程序无法调用 sub() 方法,说明 this 的编译时类型是 Base 对象。

三、结论

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

因此,程序访问 this.i 时,将会访问 Base 类中的 i,即输出 2;执行 this.display() 时,实际表现出 Derived 对象的行为,即输出 Derived 对象的实例变量 i,结果为 0.

说明4

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值