3.3.4 多态的应用
多态一般分为两种:
- 重载式多态,也叫编译时多态。也就是说这种多态在编译时已经确定好了。
- 重写式多态,也叫运行时多态。这种多态通过动态绑定(dynamic binding)技术来实现,是指在执行期间判断所引用对象的实际类型,根据其实际的类型调用其相应的方法。也就是说,只有程序运行起来,你才知道调用的是哪个子类的方法。这种多态通过方法的重写以及向上转型来实现。
对象类型转换主要分为以下两种情况:
- 向上转型:子类对象→父类对象。
- 向下转型:父类对象→子类对象。
对于向上转型,程序会自动完成,而向下转型时,必须指明要转型的子类类型。
例1:
class Animal{ //父类,动物类
public void eat(){}
public void shout(){}
}
class Cat extends Animal{ //子类,猫
public void eat(){
System.out.println("吃鱼和猫粮");
}
public void shout(){
System.out.println("喵喵喵!");
}
}
class Dog extends Animal{ //子类,狗
public void eat(){
System.out.println("吃骨头和狗粮");
}
public void shout(){
System.out.println("汪汪汪!");
}
}
public class Test{
public static void show(Animal a){
a.eat();
a.shout();
}
public static void main(String[] args) {
Animal a = new Cat(); // 向上转型
a.eat(); // 调用的是 Cat 的 eat
Cat b = (Cat)a; // 向下转型
b.shout(); // 调用的是 Cat 的 shout
}
}
上面的程序输出:
吃鱼和猫粮
喵喵喵!
向上转型,就是创建子类的对象new Cat(),转型成父类的对象Animal a,通过这个父类对象a调用方法eat()时,实际调用的是子类Cat中重写后的eat()方法。
注意:父类对象a只能调用父类中已经存在的方法,比如eat()。如果有个方法,父类没有,而子类有,父类对象a就不能调用
向下转型,就是将父类对象a强制转换成子类型。
注意:在进行对象的向下转型前,必须发生对象向上转型。
换句话说,在向下转型时,不能直接将父类实例强制转换为子类实例,这个父类实例必须是事先从子类转型成父类的实例,否则程序会报错。
多态的实现方式:
- 父类与子类继承
- 接口
- 抽象类和抽象方法
接口和抽象类也可以实现多态:
例2
public interface Printer{
public void printWord();
public void printExcel();
}
public class HPPrinter implements Printer{
public void printWord(){
System.out.println("惠普彩色打印机打印word文档,打印彩色word文档");
}
public void printExcel(){
System.out.println("惠普彩色打印机打印excel表格,打印彩色excel表格");
}
}
public class EpsonPrinter implements Printer{
public void printWord(){
System.out.println("爱普生黑白打印机打印word文档,打印黑白word文档");
}
public void printExcel(){
System.out.println("爱普生黑白打印机打印excel表格,打印黑白excel表格");
}
}
public class Test{
public static void myprint(Printer p){
p.printWord();
p.printExcel();
}
public static void main(String[] args){
Pointer p1=new HPPrinter();
myprint(p1);
Pointer p1=new EpsonPrinter();
myprint(p2);
}
}