多态
什么是多态
多态:同一个对象,在不同时刻表现出来的不同形态。
多态的前提和体现:
- 有继承、实现关系
- 有方法重载
- 有父类引用指向子类对象
多态解决什么问题
我们可以先观察以下代码示例:
-
创建一个行为接口(老师和学生的行为)
public interface Behivor { public void play(); public void play1(); }
-
老师和学生分别有不同行为
public class Teacher implements Behivor { @Override public void play1() { System.out.println("老师上班"); } @Override public void play() { System.out.println("老师教书"); } } public class Student implements Behivor{ @Override public void play1() { System.out.println("学生上学"); } @Override public void play() { System.out.println("学生背书"); } }
-
创建测试类
package java_polymorphic; public class Test { public static void main(String[] args){ Teacher teacher = new Teacher(); Student student = new Student(); // teacher.play(); / // teacher.play1();//冗余代码 // // student.play(); //冗余代码 // student.play1();/ //修改上面的冗余代码 method(student); method(teacher); } public static void method(Behivor p){ //将老师和学生行为进行封装 p.play(); p.play1(); } }
由此我们发现:
- 多态可以提高代码复用性
- 多态可以提高代码扩展性
多态使用
//多态代码格式(大类型包含小类型):
父类 对象 = new 子类();
多态使用时的注意事项
- 多态中:父类和子类拥有一摸一样的成员变量时:
- 编译时:以父类中的成员变量为主
- 运行时:使用父类中的成员变量
- 多态中:父类和子类拥有一摸一样的成员方法时:
- 编译时:以父类中的成员方法为主(查看父类中有没有这个成员方法,没有则报错)
- 运行时:以子类中的成员方法为主(调用子类中重写的成员方法)
多态的转型
-
向上转型(联想自动类型提升)
父类型 父引用 = new 子类();//弊端:父引用不能使用子类特有成员
-
向下转型(联想强制类型转换, 可解决父类不能使用子类中的特有成员)
子类型 对象 = (子类型) 父引用
注意:
-
向下转型时容易发生类型转换异常
解决方案:instanceof
if(父类对象 instanceof 子类型){ 子类型 对象 = (子类型)父类引用对象; 对象.特有成员 } instanceof:判断关键字左边的变量,是否是右边的类型,返回boolean类型结果
-
多态代码的书写
-
创建对象
//父类型 父引用 = new 子类(); Father f = new Son();
-
作为参数
public void method(Father f){ f.成员 }
-
作为返回值
public Father getSon(){ //返回子类型 return new Son(); }