运算符的多态

打个比方,加号在 Java 里面既可以表示两个数相加,也可以表示字符串的拼接。

类的多态

  1. class Hero {
  2. void attack() {
  3. System.out.println("发出一次攻击");
  4. }
  5. }
  6. class ADHero extends Hero {
  7. @Override
  8. void attack() {
  9. System.out.println("发出一次AD攻击");
  10. }
  11. }
  12. class APHero extends Hero {
  13. @Override
  14. void attack() {
  15. System.out.println("发出一次AP攻击");
  16. }
  17. }
  18. public class Main {
  19. public static void main(String []args) {
  20. Hero a = new ADHero();
  21. Hero b = new APHero();
  22. a.attack();
  23. b.attack();
  24. }
  25. }

a 和 b 同样都是 Hero 类型,但是执行相同的 attack 方法时,却得到了不同的结果。
概括起来就是,对于同一个父类(接口),你在调用他的时候却拥有不同的运行态,这就是多态

类的多态的前置条件

  1. 存在继承关系
  2. 子类要重写父类的方法
  3. 父类数据类型的引用指向子类对象

多态的意义

我没做过实际开发,就随便讲点简单的。
打个比方,我们开发一个游戏,一个角色可以使用多种药品,例如能量饮料,止痛药,肾上腺素等等(实际上我们可能需要写更多的药品)。
如果没有多态,那么我们就需要写大量不同名称的方法,例如 use1,use2,use3,诸如此类,调用起来离谱的一。在这时,我们便可以使用多态的概念,设计一个 Medicine 父类,提供 use 方法,每个子类只需要重写它即可。这样的话,我们在编写角色时,只需要对于每个药品使用 use 即可,无需记住他们纷繁复杂的名字。

扩展:编译时多态

上面的类的多态特指运行时多态,它是基于重写(覆盖)的。
如果放宽一下要求,发散下思维,你会发现有啥东西也比较符合多态定义呢?没错,就是重写!
类似的,我们在代码段里面,只是纯粹的调用方法,但我们并没有关心到底用的是哪一个,直到编译的时候,编译器根据我们传入的参数来判断究竟应该调用哪一个方法,这也被称作编译时多态。
这是扩展知识,不做深入讲解(因为我自己都云里雾里的),感兴趣可以自行百度。