2.多态

2.多态

(1)多态的概念和实现

可以有下面这样的赋值语句,因为鸵鸟就是一种鸟:

这样的赋值造成对象b有两种类型,左边的引用类型是Bird,而运行时真正赋值给b的是右边的Ostrich对象。可以说b的引用类型是Bird,而b的运行时类型是Ostrich,那么b.fly()是调用Bird的fly(),还是Ostrich的fly()呢?因为b实际上是一个Osctrich对象,显然调用Ostrich的fly()是合理的。所以当引用类型和运行时类型有重写的方法时,应调用运行时类型中的方法。

【代码16.27】多态例程

现在定义一个Bird类型的数组,在这个数组中有Bird对象,也有Ostrich对象。

【代码16.28】多态例程

运行结果:

老鹰正在飞

鸵鸟虽然是鸟,但是只能在地上走

在代码16.28的第6行中,数组中的对象循环调用fly(),但数组中不同对象的运行结果会不同,这就表现出了多态。对于引用类型为父类的对象,可以传入父类或者子类的对象,当父类和子类存在重写方法时,实际调用的方法是根据运行时类型动态绑定的。多态是指同一个方法调用发生在不同的对象上时会产生不同的结果,因为虽然代码中调用的方法名相同,但实际运行时调用的方法却是不同的。

注意,编译是按照引用类型进行语法检查的。

b2的运行时类型是Ostrich,引用类型是Bird。在编译的时候,是按照引用类型Bird检查的,而Bird类中是没有jump()方法的,所以上述语句会编译出错,虽然Ostrich类中是有jump()方法的。

(2)实现多态的条件

实现多态的条件如下。

第一,存在父类和子类之间的继承关系。

第二,子类中重写了父类的方法。

第三,父类引用指向子类对象。

【代码16.29】

需求:模拟出试卷和批改试卷。每个题目包括题号、题面、选项数组,题目类型分为单项选择题和多项选择题。

①父类:Question(题目)。

②子类:SingleQuestion(单项选择题)。

在子类SingleQuestion中。代码的第1行继承父类Question;代码的第9行重写父类方法public boolean check(String[]ans)。

③子类:MultiQuestion(多项选择题)。

在子类MultiQuestion中,代码的第2行继承父类Question;代码的第10行重写父类方法public boolean check(String[]ans)。

④Test Question(测试类)。

在Test Question测试类中,代码的第7行定义父类Question数组;代码的第8行到第11行在引用类型为父类的数组中,放入子类的对象;代码的第19行、第20行统一调用check()方法进行答案批改,对于单选题调用SingleQuestion类的check()方法,对于多项选择题调用MultiQuestion类的check()方法,这体现了多态。