“继承”是解释超类的静态方法的正确术语,可以由子类访问吗?

澄清:此问题与访问修饰符无关

确认 B.m() 和 b.m() 语句在以下代码中均有效:

class A {
  static void m() { //some code }
}

class B extends A {
}

class Example {
  public static void main (String [] args) {
    B.m(); // running A's m() static method
  }

  public void try() {
    B b = new B();
    b.m(); // running A's m() static method
  }
}

我的问题是,我们能说“静态方法是继承的”吗?

如果“inherited”是正确的术语,如果我们向B类添加一个方法,我们将静态类的签名相同:

class A {
  static void m() { //some code }
}

class B extends A {
  static void m() { //some code }
}

class Example {
  public static void main (String [] args) {
    B.m(); // running B's m() static method
  }

  public void try() {
    B b = new B();
    b.m(); // running B's m() static method

    A a = new B();
    a.m(); // running A's m() static method, no polymorphism
  }
}

在这种情况下,请注意我们没有多态性,说“静态方法被继承但不被覆盖,子类静态方法隐藏超类静态方法”是正确的术语吗?

最后一个疑问,对于这两个术语,“继承”和“覆盖”,哪一个与术语“多态性”直接相关?


答案 1

是的,我认为“继承”在这里是正确的术语,即使它不像它可能的那样具有描述性。来自 Java 语言规范的第 8.4.8 节

类 C 从其直接超类和直接超接口继承超类的所有非私有方法(无论是否抽象),这些方法和超接口是公共的、受保护的或使用默认访问权限声明的,并且既不被类中的声明覆盖 (§8.4.8.1) 也不隐藏 (§8.4.8.2)。

这没有指定实例方法,但是对于允许隐藏或重写的内容有特定的限制,如果没有继承静态方法,这将没有意义。

实际上,我只是将静态方法视为“无需限定即可访问”,而不是其他任何东西,因为它们不参与多态性等。我认为值得非常清楚这一点 - 例如,一个静态方法可以隐藏继承的方法,但它不能覆盖它。

换句话说,虽然我认为“继承”在技术上是正确的,但我会尽量避免使用它,而没有任何进一步的解释。

对于你的第二个问题,我想说的是,基于上述内容,覆盖与多态性有关,但继承并不一定。

(我还强烈建议您避免调用静态方法“via”变量,并在您指定名称的位置使用声明静态方法的类的名称。我知道这不是问题的一部分,但我想我还是会添加它......)


答案 2

我认为试图将“继承”和“覆盖”这样的词应用于这种事情是没有成效的。它具有误导性,因为它给人的印象是,虚拟实例方法的情况具有可比性,而您指出事实并非如此。

(但正如 Jon Skeet 所指出的,Java 语言规范与我的意见不一致,它将它们组合在同一部分中。


推荐