Java多态问题:为何输出为Wuff Ringding而非Ringding Ringding?
嘿,这个问题其实是Java里编译时方法匹配和运行时多态的典型“坑”,我来给你拆解开讲清楚~
先明确两个核心规则
- 方法重载是编译时确定的:编译器只会看变量的编译类型(就是你声明变量时写的那个类型,比如
Hund hybrid里的Hund),以及方法参数的编译类型,来决定调用哪个重载版本。 - 方法重写是运行时确定的:只有当调用的是被子类重写的实例方法时,才会根据对象的实际类型(比如
new Fuchs()),执行子类的实现。
分析第一行输出:System.out.println(hybrid.spielen(foxi));
- 变量
hybrid的编译类型是Hund,所以编译器只会在Hund类里找spielen方法——Hund里只有一个spielen(Hund h),参数是Hund类型。 foxi的编译类型是Fuchs,它是Hund的子类,可以向上转型为Hund,完全匹配Hund.spielen(Hund)的参数要求。- 运行时,执行
Hund.spielen(Hund)的代码:return "Wuff" + h.bellen();- 前缀"Wuff"是
Hund类里写死的,不会因为对象实际类型变化而改变。 h.bellen()这里,h的实际类型是Fuchs(你传的是foxi),所以多态生效,调用Fuchs重写的bellen(),返回"Ringding"。
- 前缀"Wuff"是
- 拼接起来就是
WuffRingding(你写的空格应该是输入时的小失误)。
分析第二行输出:System.out.println(foxi.spielen(hybrid));
- 变量
foxi的编译类型是Fuchs,它有两个spielen方法:自己定义的spielen(Fuchs f),以及从Hund继承来的spielen(Hund h)。 - 参数
hybrid的编译类型是Hund——编译器只认编译类型,它不知道hybrid实际是Fuchs实例,不会把Hund类型的变量传给参数为Fuchs的方法(毕竟不是所有Hund都是Fuchs),所以只会匹配参数为Hund的重载版本。 - 最终还是调用
Hund.spielen(Hund)方法,前缀"Wuff"加上h.bellen()的"Ringding",结果还是WuffRingding。
如何得到你预期的RingdingRingding?
如果想让foxi调用自己的spielen(Fuchs)方法,你需要把hybrid强制转型为Fuchs(前提是你确定它的实际类型就是Fuchs):
System.out.println(foxi.spielen((Fuchs) hybrid));
这样编译器就会匹配Fuchs.spielen(Fuchs),前缀是"Ringding",加上f.bellen()的"Ringding",就能得到你想要的结果啦。
内容的提问来源于stack exchange,提问作者123 bodyuilding
相关产品推荐
相关产品推荐

