52. 明智审慎地使用重载

This commit is contained in:
sjsdfg 2019-03-09 13:59:52 +08:00
parent 81f809101c
commit 4fb6b7a4f2

View File

@ -33,7 +33,7 @@ public class CollectionClassifier {
  您可能希望此程序打印 Set然后是 List 和 Unknown Collection 字符串,实际上并没有。 而是打印了三次 Unknown Collection 字符串。 为什么会这样? 因为`classify`方法被重载了,**在编译时选择要调用哪个重载方法**。 对于循环的所有三次迭代,参数的编译时类型是相同的:`Collection<?>`。 运行时类型在每次迭代中都不同,但这不会影响对重载方法的选择。 因为参数的编译时类型是`Collection<?>,`,所以唯一适用的重载是第三个`classify(Collection<?> c)`方法,并且在循环的每次迭代中调用这个重载。
  此程序的行为是违反直觉的,因为**重载overridden方法之间的选择是静态的而重写overridden方法之间的选择是动态的**。 根据调用方法的对象的运行时类型,在运行时选择正确版本的重写方法。 作为提醒,当子类包含与父类中具有相同签名的方法声明时,会重写此方法。 如果在子类中重写实例方法并且在子类的实例上调用,则无论子类实例的编译时类型如何,都会执行子类的重写方法。 为了具体说明,请考虑以下程序:
  此程序的行为是违反直觉的,因为**重载overloaded方法之间的选择是静态的而重写overridden方法之间的选择是动态的**。 根据调用方法的对象的运行时类型,在运行时选择正确版本的重写方法。 作为提醒,当子类包含与父类中具有相同签名的方法声明时,会重写此方法。 如果在子类中重写实例方法并且在子类的实例上调用,则无论子类实例的编译时类型如何,都会执行子类的重写方法。 为了具体说明,请考虑以下程序:
```java
class Wine {