首先一个方法对外暴露的信息有以下几个——
权限、是否静态、是否final、返回类型、方法签名、异常类型。
其中,按照Effective Java中的约定,方法签名包括了方法名和参数列表。
重写指的是父类中的方法无法满足子类的需求,子类通过重写一个方法的方式来覆盖父类的方法。
而重写方法的某个信息需要与被重写方法的那个信息一致,才能让编译器知道,方法重写发生了。
那个是信息就是方法签名,子类的方法会去重写(override)父类中与其方法签名一致的方法,
方法签名一致,指的是方法名一致且参数类型、个数、类型顺序都一致。
红框证明了重写确实发生了,绿框则表示方法的“是否final”不一致并不影响方法重写,
并且,参数的变量名(b和a)不一致也不影响方法重写,因为它们是提供给方法体内部使用的。
但是,尚不能证明 “权限、是否静态、返回类型、异常类型 需要与被重写的方法一致才能发生重写” 是错误的,
而实际上,方法重写确实对上述信息有所限制。
方法重写还需要遵守一定的限制,否则编译器会报错。
1、重写方法的权限只能比被重写方法的大,不能比它的小。
2、是否静态需要与被重写方法一致
3、重写方法可以是final,也可以不是final(被重写的方法不可能是final的,否则它无法被重写)
4、返回类型需要与被重写方法一致
5、异常类型的捕获精度只能比被重写方法的更精确(或是不抛异常),而不能比它的更宽泛
综合以上五点,并不是子类的方法与父类的方法相同时,重写才会发生,而是在方法签名相同时便发生了。重写发生了以后子类方法受到了父类方法的一些限制。
那么方法签名不同的方法之间有什么关系呢?
1、仅仅方法名不同、或是都不同。
如果两个方法方法名都不同……那么他们毫无关系,
就像Math.asin(double d)和Math.atan(double d)除了方法名不一样,其他的方法信息都一样,
但是它们完全是两个方法。都不同的情况显然也是同理。
2、仅仅参数列表不同。
这种情况下,被称为方法重载(overload)。
如果有一个设计良好的方法,那么他的方法名应该能够自身作用,
现在希望这个方法能够作用在别的参数组合上,而方法作用不变,
那么最好的方式应该是再存在一个一样方法名的方法,但是拥有新的参数列表。
就像String.valueOf(boolean b)、String.valueOf(int i)……那样。