1、概述(是什么)
面向对象程序设计的三大支柱:封装、继承、多态;
多态(Polymorphism),源于希腊文字,意为"多种形式“。
现实事物经常会体现出多种形态,如学生,学生是人的一种,则一个具体的同学张三既是学生也是人,即出现两种形态。如Student类继承了Person类,一个Student的对象便既是Student,又是Person。
简单来说,多态意味着父亲类型的变量可以引用子类型的对象
前提条件:1、要有父子关系,是继承;2、在使用多态后的父类引用变量调用方法时,会调用子类重写后的方法,所以要有方法的重写。
2、动态绑定
在调用一个方法时,从源代码上看,无法确定调用了哪个对象的方法。只有在程序运行期间根据对象变量引用的实际对象才能确定此方法是哪个对象的。这种现象称之为动态绑定 (联编)。
简单说就是在运行时刻能够自动选择调用哪个方法的现象。
动态绑定的前提是:
1) 有继承,且一个父类有多个子类。
2) 在每一个子类中对继承自父类的同一个方法实现了重写。
//(如下代码对Object类进行过了重写)
3) 发生多态,即: 父类对象变量引用了不同的子类对象。
4) 父类的对象变量调用了重写的方法,即: 发生了动态绑定。从而实现了多的价值。
调用m(new Student()) (第4行)会调用在Student类中定义的toString方法。
调用m(new Person()) (第5行)会调用在Person类中定义的toString方法。
调用m(new0bject()) (第6行)会调用在object类中定义的toString方法。
匹配方法的签名和绑定方法的实现是两个不同的问题。引用变量的声明类型决定了编译时匹配哪个方法。在编译时,编译器会根据参数类型、参数个数和参数顺序找到匹配的方法
动态绑定工作机制:
假设对象O是c1、2、3...n的实例,C1 是 C2的子类,C2 是C1 的子类...所以在java中,Cn是最通用的类,C1是最特殊的类;
当O调用某方法P时,JVM就会在n个类中以此寻找p直到找到为止,一旦找到,便停止查找。
//使用父类引用指向子类对象,再调用某一父类中的方法时,不同子类会表现出不同结果
3、对象转换和instanceof操作符
对象转换:一个对象的引用可以类型转换为对另外一个对象的引用。
向上转换:总是可以将一个子类的实例转换为一个父类的变量,因为子类的实例总是它的父类的实例,(也可以理解为自动转换)
//将对象new Student()赋值给一个Object类型的参数
Object o = new Student();
m(o);
---------
student b = o;//编译错误,student对象总是Object的实例,而Object不一定时Students的实例
//父类类型 变量名=new 子类类型();
向下转换:把一个父类的实例转换为它的子类变量,(强制转换)
发生多态时就需要将对象的引用实现向下转型(强制转换)
//利用转换标记"(子类名)"可以进行显示转换
//实现向下转换
Student() = (Student)o
//子类类型 变量名=(子类类型) 父类类型的变量;
如果父类对象不是子类的一个实例时,将会运行错误,如上:当一个对象不是Student()的实例的时候,它就不能转换成Student类型的变量,这个时候可以就可以用instanceof操作符
instanceof操作符
作用:用来判断某个对象是否属于某种数据类型。
总之,面向对象的三大特性是肥肠重要的,肯定有更多好处有待我们发现💪