02_oo_06_polymorphism

第十九章 多态(Polymorphism)

1 简介

在使用类继承关系的同时,我们也建立了一个类与类之间的关系。继承关系又被称为"is-a"关系,即子类的对象也是一种父类的对象。在我们之前使用的一个例子中,一个大一的学生也是一名学生。所以,一个Freshman的对象也是一个Student对象。

在软件设计中存在一个重要的"is-a"法则,或者又称为置换法则。这个法则指出:一个好的程序设计能够允许将任意一个父类对象置换成一个子类对象。

2 多态与动态绑定

为了实现置换法则,人们设计了多种实现方式。其中,最流行的一种方式是多态(Polymorphism),或者有时我们又称之为动态绑定。动态绑定的意思是指在编译时,编译器无法确定当前函数调用会调用哪个函数。这需要等到运行时检查具体对象的类型才能确定。

在下面的代码示例中,我们声明了一个抽象的Student类,它有一个抽象的成员方法yearOfGraduation(),用于获取学生毕业的年份。

public abstract class Student {
    public abstract int yearOfGraduation ();
}

然后,我们分别定义四个类Freshman、Sophomore、Junior和Senior,分别用于表示大一、大二、大三和大四的学生。它们都继承自Student,并且覆盖了Student类的yearOfGraduation()方法。我们假设今年是2010年。

public class Freshman extends Student {
    @Override
    public int yearOfGraduation () {
        return 2014;
    }
}

public class Sophomore extends Student {
    @Override
    public int yearOfGraduation () {
        return 2013;
    }
}
public class Junior extends Student {
    @Override
    public int yearOfGraduation () {
        return 2012;
    }
}

public class Senior extends Student {
    @Override
    public int yearOfGraduation () {
        return 2011;
    }
}

那么,当我们分别创建这四个类的对象后,分别调用yearOfGraduation()方法所得到的结果是不同的。这是因为Java语言在这里应用了多态的特性,哪个方法被调用取决于对象的类型。程序需要在运行时动态的决定对象的类型和调用的方法。

public class StudentCenter {
    private static void printGraduationYear(Student s) {
        System.out.println(s.yearOfGraduation());
    }

    public static void main(String[] args) {
        // 会打印 2014
        printGraduationYear(new Freshman());

        // 会打印 2013
        printGraduationYear(new Sophomore());

        // 会打印 2012
        printGraduationYear(new Junior());

        // 会打印 2011
        printGraduationYear(new Senior());
    }
}

Java语言多态的特性为Java程序开发提供了极大的灵活性和可扩展性。从上面的代码示例可以看到,StudentCenter类的静态方法printGraduationYear()的逻辑是固定的,它向标准输出打印学生毕业的年份。这个方法可应用于大一至大四的所有学生对象上。但是,在该方法中,我们无法知道打印的结果是什么,因为我们并不知道传入对象的类型。

假如,我们需要扩展以支持研究生的功能。那么,我们可以创建一个新类Graduate,表示研究生。但是,我们不需要改变printGraduationYear()方法的实现,就能支持打印研究生的毕业年份。这也是为什么Java语言的多态特性被广泛的应用于软件设计之中。

我们将在下一章详细介绍Java多态特性的实现细节。开发人员常常将Java语言的多态特性分为动态多态(Dynamic Polymorphism)静态多态(Static Polymorphism)。我们上述介绍的是动态多态特性,即程序在运行时动态的决定调用的方法。而静态多态则是指Java方法重载特性(Overloading),即在编译时,程序根据调用参数的个数和类型,决定所调用的方法。我们将会在后续章节介绍方法覆盖和方法重载的内容

3 小结

多态特性是Java程序设计中最为重要的特性之一。通过使用多态特性,程序能够提供更好的扩展性,以便于开发出功能更加丰富、更加强大的应用程序。我们将在下一章中介绍一种常常用于实现多态特性的技术Virtual Table

上一章
下一章

注册用户登陆后可留言

Copyright  2019 Little Waterdrop, LLC. All Rights Reserved.