为了账号安全,请及时绑定邮箱和手机立即绑定

变量的编译时类型和运行时类型

标签:
Java

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

public class StudyVisitorSonVar {public static void main(String[] args) {new Cricle("圆形");}}class Shap{public String desc;public Shap() {//该变量访问它引用的对象的实例变量时,该实例变量的值由声明该变量的类型即Shap决定//通过该变量调用它引用的对象的实例方法时,该方法行为将由它实际所引用的对象即Cricle来决定this.desc = getDesc();}public String getDesc() {this.desc = "形状";System.out.println("Shap 父类的描述为:" + this.desc);return desc;}public void setDesc(String desc) {this.desc = desc;}}class Cricle extends Shap{public String desc;public Cricle(String desc) {this.desc = desc;}@Overridepublic String getDesc() {System.out.println("Cricle 子类的描述为:" + this.desc);return this.desc;}}运行结果为:Cricle 子类的描述为:null

之所以会出现这种结果是因为调用子类构造器前会隐式调用父类无参构造器,this.desc这个this虽然代表Cricle对象,但它却位于Shap构造器中,它的编译时类型是Shap,而它实际引用一个Cricle对象。

当变量的编译时类型和运行时类型不同时,通过该变量访问它引用的对象的实例变量时,该实例变量的值由声明该变量的类型决定,但通过该变量调用它引用的对象的实例方法时,该方法行为将由它实际所引用的对象来决定。这时候就会调用子类的getDesc()方法,因为子类的desc成员变量还没有被初始化所以输出结果为null。

所以需要注意如果父类构造器调用了被子类重写的方法,且通过子类构造器来创建子类对象,不管是显式还是隐式调用了这个父类构造器就会导致子类的重写方法在子类构造器的所有代码之前被执行,从而导致子类的重写方法访问不到子类的实例变量值的情形

原文出处

点击查看更多内容
TA 点赞

若觉得本文不错,就分享一下吧!

评论

作者其他优质文章

正在加载中
  • 推荐
  • 评论
  • 收藏
  • 共同学习,写下你的评论
感谢您的支持,我会继续努力的~
扫码打赏,你说多少就多少
赞赏金额会直接到老师账户
支付方式
打开微信扫一扫,即可进行扫码打赏哦
今天注册有机会得

100积分直接送

付费专栏免费学

大额优惠券免费领

立即参与 放弃机会
意见反馈 帮助中心 APP下载
官方微信

举报

0/150
提交
取消