Java:为何父类变量需强转后才能调用子类独有方法?
为什么父类引用指向子类对象时,必须强转才能调用子类独有方法?
这个问题戳中了Java静态类型检查的核心逻辑,咱们掰开揉碎了说:
1. 编译器只认变量的「静态类型」,不认实际指向的对象
你看代码里的变量b,它的静态类型是Ball——也就是编译器在编译阶段只会把它当成Ball类的实例来处理。哪怕你实际让它指向了SoftBall对象,编译器也不会在编译时去追踪这个变量的实际指向。
因为Ball类里根本没有riseBall()方法,所以如果直接写b.riseBall(),编译器会直接报错:“找不到这个方法!”,它才不管你运行时b到底是什么东西。
2. 强转是在给编译器“递话”
(SoftBall)b这个强转操作,本质是你在告诉编译器:“我打包票,这个b实际指向的就是SoftBall对象,你就把它当成SoftBall来处理吧!”
当编译器接收到这个“保证”后,就会把变量的静态类型临时切换为SoftBall,这时候自然就能调用SoftBall独有的riseBall()方法了。
3. 注意:强转有风险,判断需先行
这里要提个醒:如果b实际指向的不是SoftBall(比如指向了BaseBall这类其他子类对象),强转就会抛出ClassCastException异常。所以实际开发里,最好先做类型判断:
if (b instanceof SoftBall) { SoftBall s = (SoftBall)b; s.riseBall(); }
举个接地气的例子
把这个逻辑套到生活里就好懂了:你手里拿了一个标着「水果」的袋子(父类引用Ball b),里面其实装的是苹果(子类对象SoftBall)。
别人看到你拿的是「水果袋」,只会默认你能做“洗水果”这种所有水果都能做的事(父类通用方法),但不会默认你能做“削苹果皮”这种只有苹果才有的操作(子类独有方法)。你必须先告诉别人“这袋子里装的是苹果”(强转),别人才会允许你去做削苹果皮的动作。
内容的提问来源于stack exchange,提问作者Mark Shuffer
相关产品推荐
相关产品推荐

