定义
注意上图红字是强调在继承、实现情况下才会产生多态
记住:左边对象范围大(如父类,被实现的接口),右边对象范围小(如子类,实现的接口),也就是说左边对象包含右边对象,如人包含学生,人包含老师。
对第一张图中具体代码体现说明如下:
1.人既可以使学生,也可以是老师,例如青年时是学生,中年时突然成为老师了(对象多态)
2.run()方法,例如青年时学生跑得快,中年时跑得慢(行为或方法多态)
3.这样就体现了多态的好处,只需跟换对象(学生,老师),那么他们的行为也会随之改变,不需要修改所调用方法的代码
多态性具体案例理解
现在来看下面的具体案例,代码如下:
口决:方法调用时编译看左边,运行看右边
解释:编译时(也就是写代码时)若左边对象中没有要调用的方法则会立马报错,运行时(也就是点击运行按钮后),若右边对象中没有要调用的方法则点击运行按钮后则去调用父类方法,有要调用的方法那当然就是这个要调用的方法咯。
现在对上面的具体案例进行分析理解
*编译看左边(编译,也就是写代码时看有没有红色报错)
1.下面是编译看左边没有要调用的方法(不能正常编译)
2.编译看左边正常情况(能正常编译)
*运行看右边(点击运行按钮后)
在能正常编译后,再看具体执行那个方法(为了体现多态性)
1.运行看右边找不到要调用的方法
输出结果为:人可以跑
2.运行看右边正常情况
输出结果为:老师跑的慢
先编译(也就是写代码没红色报错),再点击运行按钮
上面综合案例运行时看右边的两种情况就解释了多态性,根据能不能找到要调用方法,其对应的输出结果就会不同。
注意事项
1.
属性不谈多态性,见下面代码案例
口诀:编译看左边,运行看左边
2.
多态下不能直接调用子类的独有方法:就是假如子类有一个方法,并且这个方法没有重写父类方法,那么它就是独有的方法,而现在要调用这个方法,在编译阶段就不能编译了,因为父类中没有该方法(编译看左边)。要使用该子类独有的方法必须强制类型转换为子类。
现在看下面案例,子类Student独有方法为test(),要使用test必须强制类型转换
3.
对于强转后的ClassCastException错误,见下图:
所以java建议用instanceof来判断真正编译时的类型 所以对于上面情况的判断语句需要这样写
if(p1 instanceof Student) {//判断p1是否包含Student类 //强制类型转换语句 Student s1 = (Student)s1; }
要调用子类独有方法,并且解决强转后可能发生ClassCastException异常错误的最终解决办法见下图:
分析运行结果:第一行和第三行当然是编译看左边,运行看右边啦,第二行和第四行就是子类的独有方法。
总结