【多态】(超级详细!)
- 前言
- 一、 多态的概念
- 二、重写
- 1. 方法重写的规则
- 2. 重写和重载的区别
- 三、多态实现的条件
- 四、 向上转型
- 五、动态绑定
前言
面向对象的三大特征:封装性、继承性、多态性。
extends继承或者implements实现,是多态性的前提。
这篇文章中的多态都由继承实现。
一、 多态的概念
简单来说,多态可以理解为当不同的对象去完成时会产生不同的状态。
例如:在买火车票这个案例,对于普通人是全价,对于学生是半价,对于军人则是优先购买。
即:同一件事发生在不同对象身上会产生不同的结果
下面以小猫和小狗为例,帮助大家更好的理解多态。
动物 食物 小猫 猫粮 小狗 狗粮
二、重写
1. 方法重写的规则
重写(override):也称为覆盖。重写是子类对父类非静态、非private修饰,非final修饰,非构造方法等的实现过程进行重新编写, **返回值和形参都不能改变。即外壳不变,核心重写!**重写的好处在于子类可以根据需要,定义特定于自己的行为。 也就是说子类能够根据需要实现父类的方法。
【方法重写的规则】
- 子类在重写父类的方法时,一般必须与父类方法原型一致: **返回值类型 方法名 (参数列表)**要完全一致。
- 被重写的方法返回值类型可以不同,但是必须是具有父子关系的。
- 访问权限不能比父类中被重写的方法的访问权限更低。例如:如果父类方法被public修饰,则子类中重写该方法就不能声明为 protected。
- 父类被static、private修饰的方法、构造方法都不能被重写。
- 重写的方法, 可以使用 @Override 注解来显式指定. 有了这个注解能帮我们进行一些合法性校验. 例如不小心
将方法名字拼写错了 (比如写成 aet), 那么此时编译器就会发现父类中没有 aet 方法, 就会编译报错, 提示无法
构成重写。
2. 重写和重载的区别
重写 | 重载 |
---|---|
参数个数必须相同 | 参数个数必须不同 |
返回类型相同或存在父子关系 | 返回类型可以不同 |
访问权限不能比父类中被重写的方法的访问权限更低 | 访问权限可以 修改 |
方法重载是一个类的多态性表现,而方法重写是父类和子类的一种多态性表现。
三、多态实现的条件
- 必须是继承关系
- 涉及到子类对父类方法的重写
- 通过父类的引用调用父类的方法
同样使用上述小猫和小狗吃东西的例子
1.由上述可知:Animal是父类,Cat和Dog是子类。存在继承关系。
2.
由上述可知:Cat、Dog类中将父类Animal中的eat()方法进行了重写。
3.
上述两种主方法都实现了父类的引用。
到这里有两个疑问:
- 什么是向上转型?
- 为什么上述父类的引用调用的是子类中的eat方法?
下面将为大家一 一解答!
四、 向上转型
向上转型:实际就是创建一个子类对象,将其当成父类对象来使用。
语法格式:父类类型 对象名 = new 子类类型()
【使用场景】
- 直接赋值
- 方法传参
方法返回
注意:向上转型不能调用子类特有的方法!
五、动态绑定
-
程序在编译的时候,确实调用的是父类的eat方法。
-
当运行代码的时候,通过父类的引用,调用了父类和子类重写的那个方法,结果实际调用了子类的方法,此时我们把这种情况叫做动态绑定!
通过对动态绑定的学习,我们也对多态有了新的认识:
通过调用同一个方法,表现出的现象不一样,这种思想叫做多态。