本文共 3605 字,大约阅读时间需要 12 分钟。
8.2 实现多态
总结以上例子,在代码中实现多态必须遵循的要求可归纳如下: 2. 超类提供作为接口的方法,对子类完善或者覆盖这些方法指定规范。 3. 参与多态的子类必须完善或者覆盖这些指定的方法,以达到接口效应。 4. 编写驱动类,或者应用代码,子类向上转型为超类引用,实现多态。 8.2.1 超类提供多态接口
以计算圆形物体表面积和体积为例,讨论多态对超类的要求以及如何提供多态接口: // 完整程序存在本书配套资源目录 Ch8 名为 Shape.java public abstract class Shape { public abstract void computeArea(); public abstract void computeVolume(); public abstract double getArea(); // 新增参与多态的接口方法 public abstract double getVolume(); 除原来存在的两个抽象方法外,因为 getArea() 和 getVolume() 也涉及和参与多态功能,因此将它们定义为实现多态的接口方法。另外多态的实现不影响任何其他运算和操作,所以这个代码的其他部分无需修改。 当然执行多态的超类不必一定是抽象类。但因为在这个超类中,甚至大多数应用程序的超类中,只提供执行具体运算的方法的签名,不可能提供具体代码。所以应用抽象方法作为多态接口比较普遍。 public abstract class Employee { public abstract double earnings(); // 定义抽象方法作为多态接口 public class Manager extends Employee { public double eamings () return 0.0; 8.2.2 子类完善接口
在计算圆形物体表面积和体积的例子中, CircleShape2 继承了 Shape , Circle 继承了 CircleShape2 。 Circle 类中完善了抽象超类指定的、作为多态接口的抽象方法如下: // 完整程序存在本书配套资源目录 Ch8 名为 Circle.java public class Circle extends CircleShape2 { double volume = 0.0; //Circle 类没有体积 public void computeArea() { // 完善超类作为多态接口的抽象方法 area = Math.PI * radius * radius; public double getArea() { public void computeVolume() {} // 完善超类作为多态接口的抽象方法 public double getVolume() { 代码中完善了超类 Shape 规定的四个作为多态接口的抽象方法,实际上,已存在的 Circle 程序已经编写了其中的两个方法,只需要完善 computeVolume() 和 getVolume() 即可。 Circle 类没有体积计算,所以 ComputeVolume() 为空程序体且 getVolume() 返回值为 0.0 。 以此类推, Sphere 继承了 Circle ,覆盖了 Circle 的 computeArea() 和 computeVolume() : // 完整程序存在本书配套资源目录 Ch8 名为 Sphere.java public class Sphere extends Circle{ public void computeArea() { // 覆盖 Circle 的该方法 super.computeArea(); // 调用 Circle 的方法 public void computeVolume() { // 覆盖 Circle 的该方法 super.computeArea(); // 调用 Circle 的方法 volume = 4.0/3 * radius * area; 并且继承了 getArea() 和 getVolume() 。显而易见,抽象类和覆盖技术的应用,已经为实现多态铺平了道路。这里,只是对抽象类中指定的抽象方法,以及子类完善这些方法,从多态接口的角度加以新的内容和解释。按照这个概念代码技术,编写计算员工工资的子类也是水到渠成的事。如: public Manager extends Employee { public double earnings () { return baseSalary + meritPay + bonus; 值得一提的是,如果超类中定义的作为多态接口的方法是一个完善了的普通方法,在子类中则需覆盖它,以便实现多态。 8.2.3 如何使用多态
调用多态方法是通过向上转型,或称超类引用实现的。即向上转型后,由超类产生对子类多态方法的动态调用,如: Circle myCircle = new Circle(20.98); Shape shape = myCircle; // 向上转型或超类引用 shape.computeArea();. // 多态调用 应用链接表或集合,以及循环,则可有效地对大量的对象方法实行多态调用。本书将在以后的章节专门讨论循环、链接表和集合技术。 如下是对计算圆形物体的表面积和体积实现多态调用的代码: // 完整程序存在本书配套资源目录 Ch8 名为 CircleShapeApp.java public class CircleShapeApp{ public static void main(String[] args) { Circle circle = new Circle(12.98); Sphere sphere = new Sphere(25.55); Shape shape = circle; // 向上转型 System.out.println("circle area: " + shape.getArea()); System.out.println("circle volume: " + shape.getVolume()); System.out.println("Sphere area: " + shape.getArea()); System.out.println("Sphere volume: " + shape.getVolume()); 这里对 Circle 对象多态调用 computeVolume() 毫无意义,仅是为了演示目的。其运行结果为: circle area: 529.2967869138698 Sphere area: 2050.8395382450512 Sphere volume: 69865.26693621474 如果需要多态调用大量对象,可以使用数组和循环如下: for(int i = 0; i < objNum; i++) { // 循环 objNum 次 shape[i].computeArea(); //i 从 0 到 objNum-1 shape[i].computeVolume(); System.out.println("The area: " + shape[i].getArea()); System.out.println("The volume: " + shape[i].getVolume()); 这个循环语句也被称为多态管理循环。数组概念和技术将在本书第 10 章专门讨论。 本文转自高永强51CTO博客,原文链接:
http://blog.51cto.com/yqgao/177237 ,如需转载请自行联系原作者