重载方法与重写方法中的多态性
多态性与重载方法怎样协作呢?
如果传递Animal引用,则及时传递的实际对象是Horse,也将调用带Animal的重载方法。然而,一旦Horse伪装成Animal进入该方法,该Horse对象仍然是一个Horse,尽管希望杯传递进来的是Animal方法。
因此,多态性不会决定调用哪个重载版本,它制造决定调用方法的哪个重写版本是起作用。但有时会同时重载和重写方法。例如,Animal和Horse类形式如下:哪个重写版本时才起作用。但有时会同时重载和重写方法。例如,Animal和Horse类形式如下:
注意,Horse类有一个重载并且重写了的eat()犯法。下表列出了根据调用方式的不同,将运行3个eat()方法的哪个版本。
方法调用的代码 | 结果 |
Animal a = new Animal(); a.eat(); | Generic Animal Eating Generically |
Horse h = new Horse() | Horse eating hay |
Animal a = new Animal(); | Horse eating hay 多态性起作用——确定调用哪个 eat() 时,使用的是实际上的对象类型 (Horse) ,而不是引用类型( Animal ) |
Horse he = new Horse(); he.eat(“Apples”); | Horse eating Apples 调用重载方法 eat(String s) |
Animal a2 = new Animal(); a2.eat(“treats“); | 编译器错误!编译器发现 Animal 类没有带 String 变元的 eat() 方法 |
Animal ah2 = new Horse(); ah2.eat(“Carrots”); | 编译器错误!编译器还是看到该引用,并且发现 Animal 类没有带 String 变元的 eat() 方法。 |
考试注意事项 不要被子类的重载方法而不是重写方法所蒙骗。下面这样做是完全合法的: public class Foo { void doStuff(){} } class Bar extends Foo{ void doStuff(String s){} } Bar 类有两个 doStuff() 方法:一个是从 Foo 继承的无边元版本(没有重写),一个是在 Bar 类中定义的重载 doStuff(String s) 版本。引用 Foo 的代码只能调用无变元的版本,但是引用 Bar 的代码能够调用任意重载版本。 |
重写方法和重写方法的区别
| 重载方法 | 重写方法 |
变元 | 必须改变 | 一定不能改变 |
返回类型 | 可以改变 | 除协变式返回外,不能改变 |
异常 | 可以改变 | 可以减小或消除。一定不能抛出新的或更广的检验异常 |
访问级别 | 可以改变 | 一定不能执行更严格的限制,可以降低限制( p-proteted, c-public ) |
调用 | 引用类型决定了那个重载版本 | 对象类型决定了调用哪个方法。在运行时作出决定。 |
下图说明了在类关系中重载方法和重写方法的表现形式