上一节我们谈到了继承,继承是多态的基础,当两个类符合“is-a”关系的时候,我们可以这样说:在程序中超类出现的任何地方都可以用子类来替代,因为子类“is-a”超类。当然,要想表现出“多态”,我们还需要子类覆盖超类的方法。
下面我们举例说明:
class Animal {
private int age;
public Animal(int age){
this.age = age;
}
public int getAge(){
return this.age;
}
public void printDescription(){
System.out.println("\nAnimal is " + age + "years old-- 。");
}
}
class Cat extends Animal{
private String name;
public Cat(int age, String name){
super(age);
this.name = name;
}
public void setName(String name){
this.name = name;
}
@Override
public void printDescription(){
System.out.println("\n" + name + " Cat is " + super.getAge() + " years old。");
}
}
public class Main {
public static void main(String[] args) {
Animal redCat,blueCat,fatCat;
redCat = new Cat(5, "Red Bob");
blueCat = new Cat(7, "Blue Lisa");
fatCat = new Cat(3, "Fat Tom");
redCat.printDescription();
blueCat.printDescription();
fatCat.printDescription();
}
}
>>>out
Red Bob Cat is 5 years old。
Blue Lisa Cat is 7 years old。
Fat Tom Cat is 3 years old。
这里我们把子类的对象赋给了超类变量,Animal既可以引用它自身,也可以引用一个Animal的任意子类对象。
子类重写了超类中的printDescription方法,我们定义的是Animal类型的变量,但当我们实际运行的时候,却会根据我们实际创建的类型来调用覆盖后的方法,这就是动态绑定。
但是我们会发现直接用redCat来调用redCat.setName(“”)方法会报错,为什么呢?因为我们在Animal中并没有定义setName方法,这个方法是子类中的方法,在超类的引用中无法进行调用,这就是多态的一个缺点:无法调用子类特有的方法。但我们可以用如下的方式解决,把redCat转变为它所创建的类型:
Cat cat = (Cat)redCat;
cat.setName("All Cat");
就可以正常的使用子类的方法了。
今天太晚,后天更新一个经典的实例,只要掌握这个例子,多态也就不成问题了。