一.向上转型
在理解什么是多态之前,我们要先来知道几个概念,首先我们要知道什么叫向上转型。
向上转型顾名思义,把子类转型成父类,简单说就是用父类的引用引用子类的对象
它有以下三种表现形式:
- 直接赋值
- 方法的传参
- 返回值
二.重写
和重载不同,重写在继承时出现
重载是在一个类里面多个同名方法,但是参数类型或者个数不相同。
重写是子类重写父类的同名方法,参数类型,个数,返回值类型都必须完全相同。
注意:
被private修饰的方法,不能被重写
被final修饰的方法,不能被重写
被static修饰的方法,不能被重写
需要重写的方法的访问修饰限定符,子类的访问修饰限定符(如public)一定要大于等于父类(如protected)的访问修饰符
三.动态绑定
1.什么情况下才会发生动态绑定呢?(动态绑定发生的前提)
1.父类的引用,引用子类的对象(向上转型)
2.通过父类的引用,调用子类和父类重写的那个方法(重写)
2.那到底什么叫做动态绑定呢?
我们将代码进行反汇编
可以看到,编译的时候,调用的还是Animal的eat方法
但是最后运行的时候,调用的是cat的eat方法,这就叫动态绑定,也叫运行时多态
3.注意事项
1.父类调用子类的方法的时候只能调用子类里面重写过的那个方法,人家编译的时候都是调用的自己父类的方法,只是在运行的时候发生了动态绑定,才会执行子类重写的那个方法的。
如果是子类自己写的方法,父类不能调用,父类只能调用父类里有的方法
2.成员变量是静态绑定,所以成员变量的值在new子类对象的时候就已经确定了,动态绑定是针对一个个函数和方法而言的
静态绑定:在程序执行前,也就是编译的时候,方法已经被绑定
成员变量,fianl,static,private修饰的方法都是静态绑定
四.多态(被问了就这样回答)
如果上面的概念搞清楚了,那么什么多态就很清晰了:
首先要发生向上转型,也就是父类引用引用子类对象,无论通过是直接赋值,函数参数传递啊,返回值啊,总之要让父类引用子类对象。而且父类和子类有同名的覆盖方法,就是子类重写过父类的方法,然后通过父类的引用来调用这个同名的方法的时候,它有可能会表现出不同的行为,这个过程就是多态。
五.理解多态
public class test {
public static void main(String[] args) {
Shape shape1 = new Flower();
Shape shape2 = new Cycle();
Shape shape3 = new Rect();
drawShape(shape1);
drawShape(shape2);
drawShape(shape3);
}
public static void drawShape(Shape shape){
shape.draw();
}
}
当类的调用者在编写 drawMap 这个方法的时候, 参数类型为 Shape (父类), 此时在该方法内部并不知道, 也不关注当前的 shape 引用指向的是哪个类型(哪个子类)的实例。此时 shape 这个引用调用 draw 方法可能会有多种不同的表现(和 shape 对应的实例相关), 这种行为就称为多态。
封装和多态
- 封装是让类的调用者不需要知道类的实现细节.
- 多态能让类的调用者连这个类的类型是什么都不必知道, 只需要知道这个对象具有某个方法即可。(调用者写方法的时候,只要把参数类型设置为父类shape,不需要管以后是哪个子类对象会被当做参数传进来)
因此, 多态可以理解成是封装的更进一步, 让类调用者对类的使用成本进一步降低
六.多态的好处
- 类调用者对类的使用成本进一步降低
- 能够避免使用大量的 if - else
- 可扩展能力更强(如果要再加一种形状就很好加)