Java 中编译时多态和运行时多态之间的区别

2025年7月7日 | 阅读 5 分钟

多态是面向对象编程(OOP)中的一个基本概念。多态一词指的是“**多种形态**”的存在。这种能力增强了代码的灵活性、模块化和可维护性。

Java 中有两种多态类型:

  • 编译时多态(静态多态)
  • 运行时多态(动态多态)

编译时多态(静态绑定)

编译时多态发生在编译过程中选择要执行的方法时。它也被称为 **静态绑定** 或 **早期绑定**。它通常通过方法重载来实现,即在同一个类中有多个同名但参数列表不同的方法。

在编译代码时,Java 编译器会检查方法调用,并根据参数的数量和类型进行相应的调整。然后,它将调用与适用的方法进行绑定。

阅读更多 Java 编译时多态

示例:编译时多态

编译并运行

输出

 
8
5.6
6

这里,add() 方法通过不同的参数签名进行了重载。编译器根据参数类型在编译时将方法调用绑定到相应的方法。

编译时多态的优点

  • 通过方法重用提高代码的可读性。
  • 由于早期绑定,执行速度更快。
  • 由于行为固定,易于测试和理解。

运行时多态(动态绑定)

运行时多态发生在方法调用在运行时解析,而不是在编译时解析时。它也被称为 **动态绑定**、**晚期绑定** 或 **动态方法分派**。它通常通过方法覆盖来实现,子类为其超类中已有的方法提供特定的实现。

如果超类引用变量用于引用子类的对象,并且调用的方法取决于对象的实际类型而不是引用变量的类型,那么这就是一种多态情况。此选择发生在程序执行期间,因此称为“运行时”。请注意:

  • 它仅适用于 **方法覆盖**,不适用于方法重载。
  • 方法必须是 **非静态** 和 **非私有** 的,因为它们不参与运行时多态。

示例:运行时多态

编译并运行

输出

 
Dog barks
Cat meows   

在这种情况下,即使引用变量的类型是 Animal,实际调用的方法也取决于对象(Dog 或 Cat)。绑定发生在运行时,使其成为动态方法分派。

优点

  • 实现动态行为和代码灵活性。
  • 支持抽象和设计模式,如策略模式、状态模式和工厂模式。
  • 允许轻松扩展和维护代码,只需少量更改。

编译时多态与运行时多态的区别

方面编译时多态运行时多态
绑定时间发生在编译时。发生在运行时。
别名也称为静态绑定或早期绑定。也称为动态绑定、晚期绑定或动态方法分派。
多态类型静态多态动态多态
通过...实现通过方法重载实现。通过方法覆盖实现。
是否需要继承不需要继承。需要继承。
方法签名方法名称相同,但参数和返回类型不同。方法名称相同,参数和返回类型也相同。
引用类型的重要性引用类型决定方法调用。对象类型决定方法调用。
灵活性灵活性较低。灵活性较高。
性能比运行时多态快(由编译器解析)。比编译时多态慢(由 JVM 在运行时解析)。
示例add(int, int) vs. add(double, double)Animal a = new Dog(); a.makeSound();

何时使用哪种?

使用编译时多态,当...

  1. 我们需要多个执行相似操作但输入类型或数量不同的方法。
  2. 我们希望获得更快的性能,因为方法调用在编译期间解析。
  3. 我们不需要基于对象类型的动态行为。

使用运行时多态,当...

  1. 我们想使用抽象或接口。
  2. 我们希望在不同的类中使用同一方法的不同实现。
  3. 我们希望编写灵活且可扩展的代码,利用继承和多态行为。

为什么多态在 Java 中很重要?

多态在 Java 中至关重要,因为它支持基于接口的设计并鼓励松耦合。这意味着您的代码与接口或超类交互,而不是具体的实现,从而能够:

  • 易于维护和扩展,无需修改现有代码。
  • 更清晰地实现策略模式、观察者模式和命令模式等设计模式。
  • 减少重复,因为您可以重用通用行为并覆盖特定行为。

Java 编译时和运行时多态选择题

1. 下列哪项是 Java 中编译时多态的示例?

  1. 方法重写
  2. 方法重载
  3. 构造方法链
  4. 使用抽象类
 

答案:b)

解释:编译时多态通过方法重载实现,其中多个方法共享相同的名称但具有不同的参数列表。


2. 在运行时多态中,什么决定了要执行的方法?

  1. 仅方法名称
  2. 引用类型
  3. 对象类型
  4. 返回类型
 

答案:c)

解释:在运行时多态中,要执行的方法是根据实际对象类型确定的,即使引用是超类或接口类型。


3. 关于编译时多态,下列哪项陈述是正确的?

  1. 它通过使用接口来实现。
  2. 它需要继承。
  3. 它通过方法重载发生。
  4. 它在运行时解决。
 

答案:c)

解释:编译时多态通过方法重载实现,并且不需要继承。


4. 运行时多态的主要优点是什么?

  1. 提高性能
  2. 允许运算符重载
  3. 支持动态行为和灵活性
  4. 避免了方法重载的需要
 

答案:c)

解释:运行时多态支持动态方法分派,允许代码根据实际对象选择行为,从而提高灵活性。


5. 下列哪项功能不与运行时多态相关?

  1. 方法覆盖
  2. 动态绑定
  3. 继承的使用
  4. 编译时方法解析
 

答案:d)

解释:运行时多态与动态(晚期)绑定相关,并且方法在程序执行期间选择,而不是编译时。