2021-01-06

如何理解Java向上转型对象的思考

假如student类是people类的子类,我们可以用子类创建一个对象,并把这个对象的引用放到父类中去。比如:
People stu = new Student();
这时我们称对象stu是Student类的对象的上转型对象,上转型对象的实体由子类负责创建,但是对象的模板是根据父类来的。但会失去原子类对象的一些属性和功能,相当于对原子类对象做了简化,上转型对象不能操作子类新增的成员变量和方法(也就是父类没有的)

作用:当一个类有很多子类时,并且这些子类都重写了父类中的某个方法。如果我们把子类创建的对象的引用放到一个父类的对象中时,就得到了这个对象(子类对象)的一个上转型对象,那么这个上转型对象在调用这个方法时可以有很多形态,因为不同子类在重写父类方法时可能产生不同的行为,比如狗的上转型对象调用“叫声”方法时产生的行为是“汪汪汪”,猫类的上转型对象是”喵喵喵“。

啊经过一段时间的理解我差不多悟了一点:其实父类就相当于子类的子集!,当我们new一个子类对象时,子类中有一个隐藏的引用super会指向父类实例,所以在实例化子类之前会先实例化一个父类。所以说子类是包含父类的:在内存中,给子类分配的内存不仅子类本身所需的,还有父类实例对象的内存(比如子类对象本身的数据需要1M内存,父类本身需要2M内存,但创建子类对象时实际分配的内存是3M!因为实例化子类之前要先实例化父类)

People stu = new Student(); 我们回到这段代码,对象stu包含了父类people的内存和子类Student的内存,因为创建的的是子类对象,但是由于stu对象前面有People类型修饰它,相当于stu对象的引用(就是地址)指向Student实例对象中的People对象,二者是包含关系,所以这也解释了为何stu对象无法调用子类新增的方法(也就是父类没有的)。

这就是向上转型!我们创建的是一个子类对象,同时子类内存中包含父类,那我们可以把子类对象能调用的范围框起来,限定在父类对象拥有的当中,怎么限定?把子类对象前面的类型修饰符换成父类的。

就是原本代码:

Student stu=new Student();

stu对象前面的修饰符是Student,并且前面说过子类包含父类,所以这时候stu对象既可以访问父类有可以访问子类。
但如果我们把类型修饰符换成People:people stu=new Student(),那么stu对象的访问范围就被框在People对象中,只能访问People类所拥有的,而无法访问Student子类的。

这也是为什么向上转型往往不会出错(从子类大内存中框定范围变成小内存),而向下转型(由父类转到子类,从父类小内存拓展至子类的大内存)往往会出错,除非是已经向上转型过的再向下转型转回来(就是取消访问限制恢复原状)。

补充知识可能助于理解:对象的引用(地址)是保存在栈中的,实例化对象是保存在堆中的。实例化对象会在堆中分配内存。栈中的对象引用指向堆中分配的内存。

本人Java初学者,写这篇文章的初衷是记录自己的想法,肯定有说的不对的地方。如果您发现了错误欢迎指正,谢谢。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值