首页 > 编程笔记 > Java笔记 阅读:8

什么是多态,Java多态的具体实现(附带实例)

“多态”这个词来源于希腊语,意思是“多种形式”,最早应用于生物学,指同在一个生物群体,各个体之间存在的生理学、形态学和生化学的差异。

在 Java 中,多态是指允许同一程序指令在不同的上下文中实现不同的操作。具体来讲,当一个方法名作为一个指令时,根据执行该方法的对象类型,可能产生不同的动作。

面向对象程序设计中包括两种形式的多态,分别是编译时多态和运行时多态:
接下来主要对运行时多态进行讲解,下文提到的多态指的都是运行时多态。

多态是面向对象的重要特性,它可以提高程序的抽象程度和可扩展性,最大程度地降低类和程序模块间的耦合度。

为什么需要多态

下面通过一个现实生活中的例子来认识一下多态,这个例子模拟的是主人喂养宠物,代码如下:
class Pet { // 宠物类
    private String name = "无名"; // 昵称
    private int health = 100; // 健康值
    public void eat() {
    }
}

class Dog extends Pet { // 狗类继承自宠物类
    public void eat() { // 重写eat()方法
        System.out.println("狗狗在吃饭");
    }
}

class Cat extends Pet { // 猫类继承自宠物类
    public void eat() {
        System.out.println("猫咪在吃饭");
    }
}

class Master {
    private String name;
    public void feed(Dog dog) {
        dog.eat();
    }
    public void feed(Cat cat) {
        cat.eat();
    }
}
在上述代码中,Pet 类是父类,Dog 类和 Cat 类是子类,并且重写了父类的 eat() 方法。Master 类分别为 Dog 类和 Cat 类定义了喂食的方法,这两个方法构成了方法重载,可以实现主人喂养宠物的功能。

但是,假如主人以后要喂养更多的不同种类的宠物时该怎么办呢?比如说,现在主人要喂养鹦鹉,我们除了需要先新增一个 Parrot 类(鹦鹉类)之外,还必须在 Master 类中新增一个给鹦鹉喂食的方法。当需要删除某个宠物类时,则需要进行删除相关宠物类的代码。

那么,有没有更好的解决办法呢?这时候,就可以使用多态进行代码优化。

Java多态的含义

编程是一个将具体世界进行抽象化的过程,多态是抽象化的一种体现,即将一系列具体事物的共同点抽象出来,再通过这个抽象的事物,与不同的具体事物进行对话。对不同类的对象发出相同的消息,将会有不同的行为。

例如,公司规定所有员工在九点钟开始工作,而不需要由专业领导对财务人员说“开始财务工作”、对行政人员说“开始行政工作”…,使用专业术语来定义多态就是:同一个引用类型,使用不同的实例可以执行不同的操作,即父类引用子类对象。

下面通过代码来理解一下多态,参考代码如下:
Pet p = new Dog();
p.eat();
…
在上述代码中,我们将子类对象赋值给一个父类对象,这就是所谓的父类引用子类对象,或者说一个父类的引用指向了一个子类对象。代码在执行时调用的都是子类中重写过的 eat() 方法,而不是父类中的 eat() 方法,这就是多态。

Java多态的实现

同一个父类派生出的多个子类可被当作同一种类型,这样使用相同的代码就可以处理所有子类的对象。

在文章开头的实例程序中,Pet 类是父类,Dog 类和 Cat 类是子类,针对父类中的 eat() 方法,子类都重写了这个方法。对于代码“p.eat()”,当前赋值的是 Dog 类的对象,当然也可以是 Cat 类或其他 Pet 类的子类对象,即可能会得到多种运行结果,具体的结果取决于程序运行时父类对象 p 所指向对象的类型。

接下来,通过案例来演示多态的具体实现:
class Pet { // 宠物类
    private String name = "无名"; // 昵称
    private int health = 100; // 健康值
    public void eat() {}
}

// Dog类、Cat类重写父类的eat()方法
class Dog extends Pet { // 狗类继承自宠物类
    public void eat() { // 重写eat()方法
        System.out.println("狗狗在啃骨头");
    }
}

class Cat extends Pet { // 猫类继承自宠物类
    public void eat() {
        System.out.println("猫咪在吃鱼干");
    }
}

// 父类引用子类对象
class Master {
    private String name; // 主人的姓名

    // 通过传递参数实现父类引用子类对象
    public void feed(Pet p) {
        p.eat(); // 主人喂宠物,具体类型由传入的类型决定
    }
}

public class Demo {
    public static void main(String[] args) {
        Pet d = new Dog();
        Pet c = new Cat();
        Master m = new Master();
        m.feed(d);
        m.feed(c);
    }
}
程序的运行结果如下:

狗狗在啃骨头
猫咪在吃鱼干

通过程序结果可以发现,使用多态解决了主人喂养宠物的问题。这时不管主人将来喂养多少种宠物,我们只需要新增子类继承 Pet 类并重写 eat() 方法就可以了,而 Master 类中始终只需要一个 feed() 方法。

使用多态可以提高代码的可扩展性和可维护性,使用父类作为方法形参是实现多态的常用方式。这里要注意的是,在进行方法调用时必须调用子类重写过的父类方法,子类中独有的方法是不能通过父类引用调用到的。

相关文章