生活中的多态
多态是同一个行为具有多个不同表现形式或形态的能力。多态就是同一个接口,使用不同的实例而执行不同操作,如图所示:
现实中,比如我们按下 F1 键这个动作,同一个事件发生在不同的对象上会产生不同的结果。
- 如果当前在浏览器界面下弹出的就是浏览器的帮助文档;
- 如果当前在 Word 下弹出的就是 Word 帮助;
- 在 Windows 下弹出的就是 Windows 帮助和支持。
三个必要条件
- 继承,子类继承父类
- 重写,子类重写了父类的方法(方法名和父类同名则称为子类重写了父类的这个方法)
- 父类引用指向子类对象
java
class Shape {
void draw() {}
}
class Circle extends Shape {
void draw() {
System.out.println("Circle.draw()");
}
}
class Square extends Shape {
void draw() {
System.out.println("Square.draw()");
}
}
class Triangle extends Shape {
void draw() {
System.out.println("Triangle.draw()");
}
}
多态的实现方式
方式一:重写
方式二:接口
方式三:抽象类和抽象方法
多态示例演示
当使用多态方式调用方法时,首先检查父类中是否有该方法,如果没有,则编译错误;如果有,再去调用子类的同名方法。
要想调用父类中被重写的方法,则必须使用关键字 super。
向上转型:Animal a = new Cat();(父类引用指向子类对象)
向下转型:Cat c = (Cat)a;(子类引用指向父类对象)
java
//动物类
abstract class Animal {
abstract void eat();
}
java
//猫类
class Cat extends Animal {
public void eat() {
System.out.println("吃鱼");
}
public void work() {
System.out.println("抓老鼠");
}
}
java
//狗类
class Dog extends Animal {
public void eat() {
System.out.println("吃骨头");
}
public void work() {
System.out.println("看家");
}
}
java
public class Test {
public static void show(Animal a) {
//调用eat方法
a.eat();
// 类型判断,如果对象是猫执行猫做的事,如果是狗执行狗做的事
if (a instanceof Cat) {
Cat c = (Cat)a;
// 猫做的事情
c.work();
} else if (a instanceof Dog) {
Dog c = (Dog)a;
// 狗做的事情
c.work();
}
}
public static void main(String[] args) {
// 以 Cat 对象调用 show 方法
show(new Cat());
// 以 Dog 对象调用 show 方法
show(new Dog());
}
}
例子解析(结合代码仔细分析):
show方法的参数是Animal对象,即父类对象。
main方法中第一次调用show方法传入了子类对象,使用向上转型将子类对象(Cat)转为父类对象(Animal)的引用a,进入方法后,使用父类对象的引用a调用了eat方法,检查父类中是否有eat方法,如果没有则编译错误;如果有,则调用子类的同名方法,所以打印"吃鱼"。if语句中判断对象a属于Cat类的实例,使用向下转型将父类对象(Animal)的引用a转换为了子类对象(Cat)的引用c,使用子类对象的引用c调用work方法所以打印"抓老鼠"。
main方法中第二次调用show方法传入了子类对象,使用向上转型将子类对象(Dog)转为父类对象(Animal)的引用a,进入方法后,使用父类对象的引用a调用了eat方法,检查父类中是否有eat方法,如果没有则编译错误;如果有,则调用子类的同名方法,所以打印"吃骨头"。if语句中判断对象a属于Dog类的实例,使用向下转型将父类对象(Animal)的引用a转换为了子类对象(Dog)的引用c,使用子类对象的引用c调用work方法所以打印"看家"。
多态的优点
- 消除类型之间的耦合关系,修改维护更方便简单。
- 可替换性,对已存在代码具有可替换性。
- 可扩充性,增加新的子类不影响已存在类的多态性、继承性,以及其他特性的运行和操作。
- 接口性,向子类提供了一个共同接口,由子类来完善或者覆盖它而实现的。
- 灵活性,它在应用中体现了灵活多样的操作,提高了使用效率。
- 简化性,多态简化对应用软件的代码编写和修改过程,尤其在处理大量对象的运算和操作时,这个特点尤为突出和重要。