Java 中可以覆盖静态方法吗?

2025年7月28日 | 阅读 6 分钟

在 Java 中,覆盖(overriding)重载(overloading)面向对象编程中最重要的两个特性。当我们想要实现多态时,就会用到这些特性。

静态方法

带有 static 关键字的方法称为静态方法。换句话说,它是属于类而不是类的实例的方法。我们通过在方法名前加上 static 关键字来创建静态方法。

静态方法的主要优点是我们可以在不创建对象的情况下调用它。它是通过类名调用的。它可以访问静态数据成员并更改其值。它用于创建实例方法。静态方法的最佳示例是 main() 方法

阅读更多 Java 中的静态方法

示例:静态方法

示例

编译并运行

输出

25.0 Celsius is equal to 77.0 Fahrenheit.

方法重写

被覆盖的方法是子类中重新定义了其超类继承方法的那个方法。它是运行时多态的一种形式,允许对象根据其真实类型表现出不同的行为,即使是通用引用。

子类提供了父类已提供的某个方法的特定实现,这称为方法覆盖。父类和子类中的方法签名必须相同。在方法覆盖中,执行哪个方法是在运行时决定的。决定是根据我们调用的对象做出的。

阅读更多 Java 中的方法重写

示例:方法覆盖

示例

编译并运行

输出

Dog barks
Cat meows

我们可以覆盖静态方法吗?

不可以,我们不能覆盖静态方法。覆盖依赖于动态方法分派,而动态方法分派是基于实例工作的。然而,静态方法属于,而不属于对象。这意味着当我们调用静态方法时,它是在编译时而不是运行时解析的。因此,Java 允许方法隐藏,而不是对静态方法进行真正的覆盖。

示例:覆盖静态方法

静态方法的调用取决于调用静态方法的对象的类型。这意味着:

  • 如果使用父类对象调用静态方法,则将从父类调用静态方法。
  • 如果使用子类对象调用静态方法,则将调用子类的静态方法。

在下面的示例中,ParentClass 有一个名为 display() 的静态方法,ChildClass 也有相同的方法签名。派生类(ChildClass)中的方法隐藏了基类中的方法。

示例

编译并运行

输出

display() method of the parent class.

请注意,即使引用是 Child 类型,但调用的是 ParentClass 的方法——因为它是静态的,并且是在编译时绑定的。

请注意,上面的程序演示了方法隐藏,而不是覆盖。

如果在同一个类中声明了具有相同签名的静态方法,会怎样?

仍然,我们不能覆盖静态方法。例如,请考虑以下代码。

示例

当我们执行上面的程序时,我们会收到编译错误。

Compilation Error:
Compilation Error: Main.java:7: error: method add(int,int) is already defined in class Sum
	static int add(int a, int b) {  //overloaded method
	           ^
1 error

与覆盖不同,我们可以重载同一个类中的静态方法,但这些方法必须具有不同的参数列表。

方法重载

在 Java 中,重载方法是指同一类中具有相同名称但参数列表不同(参数的数量、类型或顺序不同)的多个方法。这称为方法重载,它是编译时多态的一种形式。

阅读更多 Java 中的方法重载

我们可以重载静态方法吗?

可以,我们可以重载静态方法。但请记住,方法签名必须不同。例如,请考虑以下 Java 程序。

示例:静态方法重载

示例

编译并运行

输出

22
33

如果我们只通过 static 关键字的不同来重载方法,可以吗?

不可以,我们不能重载仅通过 static 关键字不同的两个方法。例如,请考虑以下 Java 程序。

示例

当我们编译上面的程序时,我们会收到以下错误。

error: method sum(int,int) is already defined in class Main
    public void sum(int a, int b)   

静态方法选择题

1. 在 Java 中,静态方法可以被覆盖吗?

  1. 是的
  2. 不能
  3. 仅在子类中
  4. 仅当标记为 final 时
 

答案:B)

解释:静态方法不是实例特定的;它们属于类。因此,通过在具有相同签名的子类中声明静态方法,它们可以被隐藏但不能被覆盖。


2. 当你在子类中定义一个具有相同签名的静态方法时,会发生什么?

  1. 它会导致编译错误
  2. 它覆盖了父类的静态方法
  3. 它隐藏了父类的静态方法
  4. 它使方法抽象
 

答案:C)

解释:Java 中子类中的静态方法,如果具有相同的签名,则会隐藏超类方法,而不是覆盖它。引用类型决定了被调用的方法。


3. 以下代码会打印什么?

  1. Parent
  2. Child
  3. 编译错误
  4. 运行时错误
 

答案:A)

解释:在编译时,静态方法的解析是根据引用类型而不是对象来决定的。因此,p.show() 调用的是 Parent 的静态方法,而不是 Child 的。


4. 当在子类中定义一个具有相同签名的静态方法时,使用的术语是什么?

  1. 重载
  2. 重写
  3. 隐藏
  4. 多态
 

答案:C)

解释:当在子类中声明一个具有相同签名的静态方法时,超类中的方法被隐藏而不是覆盖。我们称之为方法隐藏。


5. 哪种关键字组合可以防止静态方法的隐藏?

  1. static final
  2. private static
  3. abstract static
  4. 以上都不是
 

答案:D)

解释:由于静态方法本身就容易被隐藏(我们不能覆盖它们,只能隐藏它们),所以没有哪个关键字可以阻止这种情况。