如何实现Java的多态

简介:

8.2  实现多态

        总结以上例子,在代码中实现多态必须遵循的要求可归纳如下:
1.          代码中必须有超类和子类继承关系。
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() {
        return area;
    }
    public void computeVolume() {}      // 完善超类作为多态接口的抽象方法
    public double getVolume() {
        return volume;
    }

 

}

 

代码中完善了超类 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 的方法
        area = 4 *  area;
    }
    public void computeVolume() {   // 覆盖 Circle 的该方法
        super.computeArea();        // 调用 Circle 的方法
        volume = 4.0/3  *  radius  *  area;
    }
}

 

并且继承了 getArea() getVolume() 。显而易见,抽象类和覆盖技术的应用,已经为实现多态铺平了道路。这里,只是对抽象类中指定的抽象方法,以及子类完善这些方法,从多态接口的角度加以新的内容和解释。按照这个概念代码技术,编写计算员工工资的子类也是水到渠成的事。如:

 

//Demo code
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;       // 向上转型
        // 多态调用
        shape.computeArea();
        shape.computeVolume();
        System.out.println("circle area: " + shape.getArea());
        System.out.println("circle volume: " + shape.getVolume());
        // 多态调用
        shape = sphere;
        shape.computeArea();
        shape.computeVolume();
        System.out.println("Sphere area: " + shape.getArea());
        System.out.println("Sphere volume: " + shape.getVolume());
    }
}

 

这里对 Circle 对象多态调用 computeVolume() 毫无意义,仅是为了演示目的。其运行结果为:

 

circle area: 529.2967869138698
circle volume: 0.0
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 ,如需转载请自行联系原作者



相关文章
|
算法 Java 程序员
在Java的编程世界里,多态不仅仅是一种代码层面的技术,它是思想的碰撞,是程序员对现实世界复杂性的抽象映射,是对软件设计哲学的深刻领悟。
在Java的编程世界里,多态不仅仅是一种代码层面的技术,它是思想的碰撞,是程序员对现实世界复杂性的抽象映射,是对软件设计哲学的深刻领悟。
224 9
|
Java 开发者
在Java面向对象编程的广阔海洋中,多态犹如一股深邃的潜流,它推动着代码从单一走向多元,从僵化迈向灵活。
在Java面向对象编程的广阔海洋中,多态犹如一股深邃的潜流,它推动着代码从单一走向多元,从僵化迈向灵活。
107 7
|
Java 开发者
那些年,我们一同踏入Java编程的大门,多态,这个充满魔法的名字,曾无数次点亮我们探索面向对象编程的热情。
那些年,我们一同踏入Java编程的大门,多态,这个充满魔法的名字,曾无数次点亮我们探索面向对象编程的热情。
112 5
|
Java 程序员
让我们一起探讨Java多态的奥秘,看看它是如何打破“一刀切”的局限,让我们的代码更加生动多彩
让我们一起探讨Java多态的奥秘,看看它是如何打破“一刀切”的局限,让我们的代码更加生动多彩
109 5
|
7月前
|
Java 编译器 程序员
java中重载和多态的区别
本文详细解析了面向对象编程中多态与重载的概念及其关系。多态是OOP的核心,分为编译时多态(静态多态)和运行时多态(动态多态)。编译时多态主要通过方法重载和运算符重载实现,如Java中的同名方法因参数不同而区分;运行时多态则依赖继承和方法重写,通过父类引用调用子类方法实现。重载是多态的一种形式,专注于方法签名的多样性,提升代码可读性。两者结合增强了程序灵活性与扩展性,帮助开发者更好地实现代码复用。
305 0
|
Java 程序员
Java中的继承和多态:理解面向对象编程的核心概念
【8月更文挑战第22天】在Java的世界中,继承和多态不仅仅是编程技巧,它们是构建可维护、可扩展软件架构的基石。通过本文,我们将深入探讨这两个概念,并揭示它们如何共同作用于面向对象编程(OOP)的实践之中。你将了解继承如何简化代码重用,以及多态如何为程序提供灵活性和扩展性。让我们启程,探索Java语言中这些强大特性的秘密。
|
10月前
|
Java
Java 面向对象编程的三大法宝:封装、继承与多态
本文介绍了Java面向对象编程中的三大核心概念:封装、继承和多态。
533 15
|
Java 编译器
封装,继承,多态【Java面向对象知识回顾①】
本文回顾了Java面向对象编程的三大特性:封装、继承和多态。封装通过将数据和方法结合在类中并隐藏实现细节来保护对象状态,继承允许新类扩展现有类的功能,而多态则允许对象在不同情况下表现出不同的行为,这些特性共同提高了代码的复用性、扩展性和灵活性。
封装,继承,多态【Java面向对象知识回顾①】
|
Java 编译器
Java——类与对象(继承和多态)
本文介绍了面向对象编程中的继承概念,包括如何避免重复代码、构造方法的调用规则、成员变量的访问以及权限修饰符的使用。文中详细解释了继承与组合的区别,并探讨了多态的概念,包括向上转型、向下转型和方法的重写。此外,还讨论了静态绑定和动态绑定的区别,以及多态带来的优势和弊端。
316 7
Java——类与对象(继承和多态)
|
存储 Java 测试技术
Java零基础-多态详解
【10月更文挑战第10天】Java零基础教学篇,手把手实践教学!
206 4