多态指的是:
同一个行为具有多个不同的表现形式或者形态的能力(多种形态、多种状态)。
向上转型:
子 === >父(upcasting)
父类引用指向子类对象叫向上转型。
又被称为自动类型转换。
父类型引用指向子类型对象。包括编译阶段和运行阶段:
编译阶段:绑定父类的方法——静态绑定
运行阶段:动态绑定子类型对象方法——动态绑定
向下转型:
父= = => 子(downcasting)
又被称为强制类型转换。
向下转型必须要进行“强制类型转换”。
什么时候向下转型?
当想要访问的方法是子类中特有的方法时,必须要进行向下转型。
创建下面这些类和方法:
class Animal { public void move(){ System.out.println("Animal在移动"); } } class Cat extends Animal { public void move(){ System.out.println("cat在走猫步"); } public void catchMouse(){ System.out.println("猫在抓老鼠"); } } class Bird extends Animal { public void move(){ System.out.println("Bird在飞翔"); } }
当访问方法仅在子类中存在时,编译阶段的静态绑定出现问题,就会发生编译错误,如下:
public static void main(String[] args) { Animal s = new Cat(); s.catchMouse(); }
所有必须要进行类型转换(向下转型):
public static void main(String[] args) { Animal s = new Cat(); //s.catchMouse(); Cat s2 = (Cat)s; s2.catchMouse(); }
向下类型转换存在着危险,例如:
public static void main(String[] args) { Animal s = new Bird(); Cat s2 = (Cat)s; s2.catchMouse(); }
Animal和Cat存在继承关系,可以向下转型,编译没有问题。但是,在实际运行过程中,在堆内存中创建的是Bird类型的对象,Cat和Bird没有继承关系,所以在运行时就会报错,如下:
如何避免这种异常的发生呢?
需要用到一个运算符:instanceof
第一:instanceof 可以在运行阶段动态判断引用指向的对象的类型。
第二:instanceof语法:引用 instanceof 类型
第三:instanceof运算符的运算结果只能是:true / false
第四:假设 A instanceof B 的运算结果是true,那么表示:
A指向堆内存中的Java对象是B类型。
多态在软件开发中有什么作用呢?
在软件开发中有一条基本原则"开闭原则(OCP)":对扩展开放,对修改关闭(尽量避免修改原有程序)。
如果我们要模拟主人(Master)喂养宠物(Pet),现有宠物有Dog,Cat。
在使用多态前
public class Master{ public void feed(Dog d){......}; public void feed(Cat d){......}; }
以上代码看出,Master与Cat,Dog之间的关系十分紧密(耦合度高),导致扩展性很差,如果想要新添加一个宠物,必须要修改Master类。
使用多态后:
public class Master{ public void feed(Pet pet){......}; }