You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

父类数据类型与子类数据类型的差异及变量类型影响探究

Java父类引用指向子类对象 vs 子类引用指向子类对象的差异

这两种写法创建的实际对象都是MySubThing实例,但引用的类型不同,会直接影响后续代码能调用的成员、多态的使用场景,具体差异如下:

1. 可访问的成员范围不同

  • 用MyThing myThing = new MySubThing();时,编译器只把myThing当作MyThing类型处理,你只能调用MyThing中定义的方法/属性(包括父类继承来的,但不包括MySubThing新增的)。哪怕MySubThing重写了MyThing的方法,执行时会走子类的实现,但子类独有的方法或属性直接调用会编译报错。
    比如如果MySubThing有个void doSubStuff()方法,用MyThing类型的myThing直接调用myThing.doSubStuff()会编译失败,必须先强制转成MySubThing类型才能调用。
  • 用MySubThing myThing = new MySubThing();时,myThing是子类类型,能直接调用MyThing的所有非私有成员,加上MySubThing自己新增的成员,不需要任何转换。

2. 多态场景的适配性不同

第一种写法是Java多态的典型应用,适合需要统一处理多个子类实例的场景:

List<MyThing> thingList = new ArrayList<>();
thingList.add(new MySubThing());
thingList.add(new MyOtherSubThing()); // 另一个MyThing的子类

for (MyThing thing : thingList) {
    thing.commonMethod(); // 遍历执行各自子类的commonMethod实现
}

这种情况下,不管集合里放的是哪个子类的实例,都能通过父类引用统一调用方法,实际执行的是子类的重写逻辑。

而第二种写法的引用是具体子类类型,没法直接放到父类类型的集合里当然可以手动向上转型,但那样就回到第一种情况了,没法直接利用多态的统一处理能力。

3. 类型转换的要求不同

  • 第一种写法如果要调用子类独有的成员,必须做向下转型,而且建议先判断类型避免ClassCastException:
if (myThing instanceof MySubThing) {
    ((MySubThing) myThing).doSubStuff();
}
  • 第二种写法本身就是子类类型,不需要转型就能调用所有子类成员;如果要转成父类类型是向上转型,这是安全且自动完成的,比如MyThing parentRef = myThing;不会有任何问题。

为什么你觉得“结果一致”?

如果你的MySubThing只重写了MyThing的方法,没有新增任何独有的成员,那两种写法调用重写方法时,执行的都是子类的实现,表面结果确实一样,但本质上第一种写法的引用被限制了父类的接口,后续如果要扩展子类功能,第一种写法需要转型才能使用,第二种则直接可用。

内容的提问来源于stack exchange,提问作者rado_rud

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.02 06:08:37