目录
引言
在正式开始介绍java多态之前,我们先来聊一聊强制类型转换。提到强制类型转换,每个编程人都再熟悉不过,不就是一种数据类型强制转换成另一种数据类型嘛,有什么好讲的呢?但大家有没有想过为什么可以强制转换呢?比如int整型数字之所以可以转换成相应的字符,正是因为它们内在存在Unicode的联系,很好理解的是存在某种关联才可以相互转换(划重点,记住这句话^ _ ^)
此外,我们也知道强制类型转换时要特别注意大范围的数向小范围的数转换(如double型转换成int型)会损失精度,要做好取舍。
在有了这些意识之后,我们其实对转型(cast)就有了一定的了解了,下面我们正式走进多态。
一、向上转型、动态绑定、向下转型
1.向上转型
让我们先看看这四个字:向上、转型。转型还算好理解,那“向上”指什么呢?看到下面这张图的‘⬆’是不是就懂了:
向上转型可以理解为子类对象地址赋值给父类对象,父类对象的父类本质不变;向上转型后的父类对象能调用 其指向的子类中重写的方法。不过前提是要存在继承关系 ,这也就像我们引言中说的要存在内在联系,而这也就得来了java多态的第一个必要条件:存在继承关系。
向上转型的使用格式是这样的:
//父类对象
Person person=new Person();
//子类对象
Student student=new Student();
//向上转型,子类对象的地址赋给父类对象(注意向上转型不用强制转换)
person=student
//或者直接写成:
Person person=new Student();
java多态的第二个必要条件就是:父类对象引用指向子类对象。 除此之外,我们知道子类继承了父类非私有的属性和方法之后一般还会重写方法或者加入一些新的属性和方法,也就是说子类一般是父类的超集。那就出现了一个问题,这样向上转型后子类中的“非共有”的方法和属性就会被舍去,即父类对象不能调用指向的 子类自己的方法。
java多态的第三个必要条件:子类重写父类方法。这样向上转型时,子类重写的方法才会覆盖掉父类中的方法。多个子类对父类方法进行重写,再通过向上转型来覆盖父类方法;这样在实际使用时,我们就可以使父类对象动态绑定子类对象,即父类对象调用不同的子类的方法,以实现不同的功能,多态性由此得以实现。
2.动态绑定(实例)
这里举一个老师课上举的例子,很好地体现了动态绑定和建模的分离思想,好好体会这段代码
用数组存放父类对象,就可以实现对大量父类对象的成批处理,只用for循环就可以代替不使用数组所要写的很多条语句,而for循环不就是做这类事情的嘛
特别注意:
showValue方法的形参是父类对象,调用showValue方法的地方传入的实参是继承并重写的子类对象,那么奇妙的事情就发生了—在函数传参的过程中,就实现了向上转型!
public static void main(String[] args){
GradedActivity[] tests = new GradedActivity[3];
//第一次考试采用五级计分制,考了75
tests[0]= new GradedActivty();
tests[0].setScore(75);
//第二次考试采用二级计分制(P或者F)。总共20题,每题分值相同,考生答错5题。
//通过的最低分数线是60分
tests[1]= new PassFailExam(20, 5, 60);
//第三次是期末考试也采用五级计分制.总共50题,每题分值相同,考试答错7题
tests[2]= new FinalExam(50,7);
//显示每次考试的分数和等级
for(int i=0; i<tests.lengh; i++){
showValue(tests[i]);
}
public static void showValue(GradedActity exam){
System.out.println("Score:"+exam.getScore()+"\t"+
"Grade:" + exam.getGrade());
3.向下转型(类似于强制转换)
向上转型是 父类对象指向子类对象,那么向下转型就是 子类对象指向父类对象。
问题在于子类对象一般含有更多的属性和方法,不能随意指向,对父类对象一定是有要求的。要求就是:能向下转型的父类对象必须是由子类对象向上转型来的。
向下转型的正确使用格式:
Student student_1=new Student();
Person person_1=student_1; //向上转型
Student student2=(Student)person_1 //向下转型,子类对象指向父类
最后附上多态的定义,巩固一下大家对多态的理解:
多态就是指程序中定义的引用变量所指向的具体类型和通过该引用变量发出的方法调用在编译时并不确定,而是在程序运行期间才确定,即一个引用变量倒底会指向哪个类的实例对象,该引用变量发出的方法调用到底是哪个类中实现的方法,必须在由程序运行期间才能决定。因为在程序运行时才确定具体的类,这样,不用修改源程序代码,就可以让引用变量绑定到各种不同的类实现上,从而导致该引用调用的具体方法随之改变,即不修改程序代码就可以改变程序运行时所绑定的具体代码,让程序可以选择多个运行状态,这就是多态性。
总结
在第一大部分中,我们讲解了向上转型、向下转型分别是什么,以及它们的区别是什么、向下转型和强制转换的相关关系等,在这个过程中也就将Java的多态讲清了,因为向上转型其实就是多态实现的一个过程;后面也通过动态绑定的实例了解了多态的实际用途、多态性对我们的编程到底有什么方便之处。学会一个知识点,不仅要清楚它是什么,更重要的是要学会它如何使用。祝学习进步!