1、理解多态思想
学了继承关系,我们知道继承关系是一种“is a”的关系,也就是说父类的一种特殊情况,我们看一下下边这个例子
class Animal {
public void eat(){
System.out.println("吃一般的食物");
}
}
class Dog extends Animal {
@Override
public void eat() {
super.eat();
System.out.println("吃肉骨头");
}
}
class Cat extends Animal {
@Override
public void eat() {
super.eat();
System.out.println("吃鱼。。。");
}
}
public class Demo {
public static void main(String[] args) {
Animal a = new Dog();
a.eat(); // 吃肉骨头
a = new Cat();
a.eat(); // 吃鱼。。。
}
}
- 子类的对象也是动物,那么可不可以认为狗/猫对象就是动物类型的对象
Animal d = new Dog();
Animal c = new Dog();
当代码像这样写的时候多态就产生了
Animal a = new Dog();
对象(a)具有两种类型:
- 编译类型:声明对象变量的类型:Animal,表示把对象看成是什么类型
- 运行类型:对象的真实类型:Dog,运行类型->对象的真实类型
- 编译类型必须是运行类型的父类或者相同
当编译类型和运行类型不同的时候,多态就产生了。
所谓多态就是对象具有多种形态,对象可以存在不同的形式
Animal a = null;
a = new Dog(); // a此时表示Dog类型的形态
a = new Cat(); // a此时表示Cat类型的形态
- 多态的前提:可以使继承关系,也可以是实现关系(接口和实现类),在开发中一般指的是第二种
- 多态的特点:把子类对象赋给父类变量,在运行时期会表现出具体的子类特征(调用子类方法)
2、多态的好处
当把不同的子类对象当作父类类型来看待,可以屏蔽不同子类对象之间的实现差异,从而写出通用的代码达到通用编程,以适应需求的不断变化。
下边的代码中 我们将上边的代码示例增加一个Person类,喂养的方法传入Animal类,根据传入的具体类型调用具体类型的方法。
class Person {
public void feed(Animal a) {
System.out.println("feeding...");
a.eat();
}
}
public class Demo {
public static void main(String[] args) {
Person p = new Person();
Dog d = new Dog();
p.feed(d); // feeding... 吃肉骨头
Cat c = new Cat();
p.feed(c); // feeding... 吃鱼。。。
}
}