跳转至

Java 多态性示例详解

简介

在 Java 编程中,多态性是面向对象编程的核心概念之一。它允许你以统一的方式处理不同类型的对象,这大大提高了代码的灵活性和可扩展性。本文将通过详细的示例深入探讨 Java 多态性的概念、使用方法、常见实践以及最佳实践,帮助你更好地理解和运用这一强大的特性。

目录

  1. 多态性基础概念
  2. 使用方法
    • 方法重写实现多态
    • 接口实现多态
  3. 常见实践
    • 在集合框架中的应用
    • 策略模式中的应用
  4. 最佳实践
    • 提高代码可读性
    • 增强代码可维护性
  5. 小结
  6. 参考资料

多态性基础概念

多态性(Polymorphism)在希腊语中意味着“多种形式”。在 Java 里,它指的是一个对象可以有多种形态。具体来说,一个父类的引用可以指向子类的对象,并且可以根据实际对象的类型来调用相应的方法。

多态性主要通过两种方式实现: 1. 方法重写(Override):子类重新定义父类中已有的方法,当通过父类引用调用该方法时,实际执行的是子类重写后的方法。 2. 接口实现(Interface Implementation):类实现接口中的方法,通过接口引用调用实现类的方法。

使用方法

方法重写实现多态

首先定义一个父类 Animal

class Animal {
    public void makeSound() {
        System.out.println("Animal makes a sound");
    }
}

然后定义两个子类 DogCat,分别重写 makeSound 方法:

class Dog extends Animal {
    @Override
    public void makeSound() {
        System.out.println("Dog barks");
    }
}

class Cat extends Animal {
    @Override
    public void makeSound() {
        System.out.println("Cat meows");
    }
}

测试多态性:

public class PolymorphismExample {
    public static void main(String[] args) {
        Animal animal1 = new Dog();
        Animal animal2 = new Cat();

        animal1.makeSound(); // 输出 "Dog barks"
        animal2.makeSound(); // 输出 "Cat meows"
    }
}

在上述代码中,animal1animal2 都是 Animal 类型的引用,但分别指向 DogCat 类型的对象。当调用 makeSound 方法时,实际执行的是子类重写后的方法,这就是通过方法重写实现的多态。

接口实现多态

定义一个接口 Shape

interface Shape {
    double calculateArea();
}

创建两个实现类 CircleRectangle

class Circle implements Shape {
    private double radius;

    public Circle(double radius) {
        this.radius = radius;
    }

    @Override
    public double calculateArea() {
        return Math.PI * radius * radius;
    }
}

class Rectangle implements Shape {
    private double width;
    private double height;

    public Rectangle(double width, double height) {
        this.width = width;
        this.height = height;
    }

    @Override
    public double calculateArea() {
        return width * height;
    }
}

测试接口实现的多态性:

public class InterfacePolymorphismExample {
    public static void main(String[] args) {
        Shape shape1 = new Circle(5);
        Shape shape2 = new Rectangle(4, 6);

        System.out.println("Circle area: " + shape1.calculateArea()); // 输出圆的面积
        System.out.println("Rectangle area: " + shape2.calculateArea()); // 输出矩形的面积
    }
}

这里 Shape 接口的引用可以指向 CircleRectangle 等实现类的对象,通过接口引用调用 calculateArea 方法时,实际执行的是实现类的具体实现,展示了接口实现的多态性。

常见实践

在集合框架中的应用

Java 的集合框架广泛应用了多态性。例如,我们可以将不同类型的对象存储在 List 中,这些对象可以是某个父类的不同子类。

import java.util.ArrayList;
import java.util.List;

public class CollectionPolymorphismExample {
    public static void main(String[] args) {
        List<Animal> animalList = new ArrayList<>();
        animalList.add(new Dog());
        animalList.add(new Cat());

        for (Animal animal : animalList) {
            animal.makeSound();
        }
    }
}

在这个例子中,List<Animal> 可以存储 DogCatAnimal 子类的对象,通过遍历 List 调用 makeSound 方法,实现了多态行为。

策略模式中的应用

策略模式是多态性的一个经典应用场景。定义一个策略接口和多个具体策略实现类,然后根据需要动态选择不同的策略。

// 策略接口
interface SortStrategy {
    void sort(int[] array);
}

// 具体策略实现类
class BubbleSort implements SortStrategy {
    @Override
    public void sort(int[] array) {
        // 冒泡排序实现
        int n = array.length;
        for (int i = 0; i < n - 1; i++) {
            for (int j = 0; j < n - i - 1; j++) {
                if (array[j] > array[j + 1]) {
                    int temp = array[j];
                    array[j] = array[j + 1];
                    array[j + 1] = temp;
                }
            }
        }
    }
}

class QuickSort implements SortStrategy {
    @Override
    public void sort(int[] array) {
        // 快速排序实现
        quickSort(array, 0, array.length - 1);
    }

    private void quickSort(int[] array, int low, int high) {
        if (low < high) {
            int pi = partition(array, low, high);

            quickSort(array, low, pi - 1);
            quickSort(array, pi + 1, high);
        }
    }

    private int partition(int[] array, int low, int high) {
        int pivot = array[high];
        int i = (low - 1);
        for (int j = low; j < high; j++) {
            if (array[j] < pivot) {
                i++;

                int temp = array[i];
                array[i] = array[j];
                array[j] = temp;
            }
        }

        int temp = array[i + 1];
        array[i + 1] = array[high];
        array[high] = temp;

        return i + 1;
    }
}

// 使用策略的类
class Sorter {
    private SortStrategy strategy;

    public Sorter(SortStrategy strategy) {
        this.strategy = strategy;
    }

    public void sortArray(int[] array) {
        strategy.sort(array);
    }
}

public class StrategyPatternExample {
    public static void main(String[] args) {
        int[] array = {64, 34, 25, 12, 22, 11, 90};

        SortStrategy bubbleSortStrategy = new BubbleSort();
        Sorter bubbleSorter = new Sorter(bubbleSortStrategy);
        bubbleSorter.sortArray(array);

        for (int num : array) {
            System.out.print(num + " ");
        }

        System.out.println();

        SortStrategy quickSortStrategy = new QuickSort();
        Sorter quickSorter = new Sorter(quickSortStrategy);
        quickSorter.sortArray(array);

        for (int num : array) {
            System.out.print(num + " ");
        }
    }
}

在策略模式中,Sorter 类通过持有 SortStrategy 接口的引用,可以动态地选择不同的排序策略,展示了多态性在设计模式中的应用。

最佳实践

提高代码可读性

使用多态性时,尽量保持代码结构清晰。通过合理的类层次结构和接口设计,使代码易于理解。例如,将相关的方法和属性放在合适的类或接口中,避免代码混乱。

增强代码可维护性

多态性使得代码更易于维护和扩展。当需要添加新的功能或修改现有功能时,可以通过创建新的子类或实现类来实现,而不需要大幅修改现有代码。同时,遵循单一职责原则,每个类或接口只负责一项职责,有助于提高代码的可维护性。

小结

多态性是 Java 中一项强大的特性,它通过方法重写和接口实现等方式,允许以统一的方式处理不同类型的对象。在实际应用中,多态性在集合框架、策略模式等场景中发挥着重要作用。遵循最佳实践,如提高代码可读性和增强可维护性,可以更好地利用多态性来构建高质量的 Java 应用程序。

参考资料