《编写高质量代码:改善Java程序的151个建议》 建议6

建议6 覆写变长方法也循规蹈矩

思考一下以下代码:

class Base
{
    void fun(int price, int...discounts)
    {
        System.out.println("Base...fun");
    }
}
class Sub extends Base
{
    @override
    void fun(int price, int[] discounts)
    {
        System.out.println("Sub...fun");
    }
}

Base base = new Sub();
base.fun(100, 50);
Sub sub = new Sub();
sub.fun(100, 50);
该程序有什么问题吗? ---- 编译通不过。 问题出在什么地方呢?

这里@Override注解是正确的,因为父类的CalPrice编译成字节码后的形参是一个int类型加上一个int数组类型,所以跟子类的参数列表是相同的,只是Eclipse会提示这不是一种很好的编程风格。

真正的问题是出在 sub.fun(100, 50) 这条语句上,提示找不到 fun(int, int) 方法。为什么通过父类调用就没问题?Why??

事实上,base对象是把子类对象做了向上转型,此时实参50传入变长参数,再经由编译器“猜测”转变成“ {50} ”数组,由子类执行。

但是直接调用子类的情况,这时编译器并不会把 50 做类型转换,因为数组本身也是一个对象,编译器还没有聪明到要在两个没有继承关系的类之间做转换。


这是一个特例,覆写的方法参数列表竟然与父类不相同,这违背了覆写的定义,并且会引发莫名其妙的错误。所以读者在对变长参数进行覆写时,如果要使用此类似的方法,请找一个小黑屋仔细想想是不是一定要如此。

所以,覆写的方法参数与父类相同、不仅仅是类型、数量,还包括显示形式

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值