多态(Polymorphism)是同一个行为具有多个不同表现形式或形态的能力。多态可以简单的理解为一种事物的多种形态,多态是面向对象编程的一个重要特性,它指的是一个类的实例(对象)可以表现出多种形态。在Java中,多态主要通过继承(inheritance)、接口(interface)和方法重写(method overriding)来实现。多态让代码编写更灵活、更易于扩展和维护。
现实中,比如我们按下 F1 键这个动作:
- 如果当前在 Flash 界面下弹出的就是 AS 3 的帮助文档;
- 如果当前在 Word 下弹出的就是 Word 帮助;
- 在 Windows 下弹出的就是 Windows 帮助和支持。
同一个事件发生在不同的对象上会产生不同的结果。
多态的优点
- 1. 消除类型之间的耦合关系
- 2. 可替换性
- 3. 可扩充性
- 4. 接口性
- 5. 灵活性
- 6. 简化性
多态存在的三个必要条件
- 继承
- 重写
- 父类引用指向子类对象:Parent p = new Child();
代码例子:
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()");
}
}
当使用多态方式调用方法时,首先检查父类中是否有该方法,如果没有,则编译错误;如果有,再去调用子类的同名方法。
// 父类
class Animal {
void makeSound() {
System.out.println("animal makes a sound.");
}
}
// 子类
class Dog extends Animal {
@Override
void makeSound() {
System.out.println("The dog barks.");
}
}
public class Main {
public static void main(String[] args) {
Animal myAnimal = new Animal(); 实例化父类对象
Animal myDog = new Dog(); 实例化子类对象并赋给父类类型
myAnimal.makeSound(); // 调用父类方法,输出: The animal makes a sound.
myDog.makeSound(); // 调用子类实例方法,输出: The dog barks.
}
}
上例中
使用Animal
类型的引用myDog
指向Dog
类型的对象。当我们调用myDog.makeSound()
时,实际上执行的是Dog
类的makeSound
方法实现,展现了多态的特性。
注意:当子类对象调用重写的方法时,调用的是子类的方法,而不是父类中被重写的方法。要想调用父类中被重写的方法,则必须使用关键字 super。
父类的属性变量(例如变量 int a)可以被继承,同时在子类中也会同时继承该变量(super.int a,继承的变量),子类中也可以再次声明一个同名(可以同类型)的变量(double a,自己声明的同名变量),两者可以同时存在,在输出时候根据对象的引用名输出。
来看代码例子:
class Animal{
public int age;
public void move(){
System.out.println("动物可以移动");
}
}
class Dog extends Animal{
public double age;
public void move(){
age = 10.00;
System.out.println("狗可以跑和走");
}
public void bark(){
System.out.println("狗可以吠叫");
}
}
class Cat extends Animal{
public void move(){
super.age = 3;
System.out.println("猫可以跳");
}
}
public class TestOverride{
public static void main(String args[]){
Animal a = new Animal(); // Animal 对象
Animal b = new Dog(); // Dog 对象
Dog c = new Dog(); // Dog 对象
Cat d = new Cat(); // Cat 对象
a.move();// 执行 Animal 类的方法
b.move();//执行 Dog 类的方法
c.move();//执行 Dog 类的方法
d.move();//执行 Cat 类的方法
Object aValue = a.age; //调用Animal中的成员变量
Object bValue = b.age; //此时还是调用的Animal中的成员变量age
Object cValue = c.age; //调用Dog类中的成员变量age
System.out.println("The type of "+a.age+" is "+(aValue instanceof Double ? "double" : (aValue instanceof Integer ? "int" : "")));
System.out.println("The type of "+b.age+" is "+(bValue instanceof Double ? "double" : (bValue instanceof Integer ? "int" : "")));
System.out.println("The type of "+c.age+" is "+(cValue instanceof Double ? "double" : (cValue instanceof Integer ? "int" : "")));// 覆盖age属性
System.out.println("The age of cat is "+d.age);
}
}
结果:
动物可以移动
狗可以跑和走
狗可以跑和走
猫可以跳
The type of 0 is int
The type of 0 is int
The type of 10.0 is double
The age of cat is 3