【问题标题】:Why is it called "method hiding"?为什么称为“方法隐藏”?
【发布时间】:2016-02-13 11:09:23
【问题描述】:

来自docs,“如果子类定义的静态方法与超类中的静态方法具有相同的签名,则子类中的方法会隐藏超类中的方法。”

我了解方法隐藏和覆盖之间的区别。但是,说子类隐藏了超类方法很奇怪,因为如果您有以下内容:

public class Cat extends Animal {
    public static void testClassMethod() {
        System.out.println("The static method in Cat");
    }
    public void testInstanceMethod() {
        System.out.println("The instance method in Cat");
    }

    public static void main(String[] args) {
        Cat myCat = new Cat();
        Animal myAnimal = myCat;
        Animal.testClassMethod();
        myAnimal.testInstanceMethod();
    }
}

调用超类的静态方法。但是根据隐藏的定义,子类中的方法就是隐藏超类中的方法。我看不到子类是如何“掩盖/隐藏”超类静态方法的,因为超类的方法是实际调用的方法。

【问题讨论】:

  • 我认为这类似于局部变量如何隐藏字段。该字段仍然可以访问(就像超类的静态方法一样),但它被隐藏了(更难访问),因为 Cat.staticMehodName() 的行为是调用 Cat 而不是 Animal。

标签: java oop inheritance polymorphism dynamic-binding


【解决方案1】:

调用超类的静态方法。

是的。但这是因为您通过在调用语句中使用超类名称限定来显式命名超类的静态方法。

如果你是这样写的main

public static void main(String[] args) {
    ...
    testClassMethod();
}

然后你会看到testClassMethodCat 版本被调用了。这里Cat.testClassMethod方法隐藏了Animal.testClassMethod方法

【讨论】:

  • 而“明确命名事物”正是人们绕过隐藏事物的方式。如Animal.testClassMethodthis.value = valueOuterClass.this.method()
【解决方案2】:

CattestClassMethod() 隐藏了Animal.testClassMethod(),因为如果Cat 类中没有静态testClassMethod()Cat.testClassMethod() 将调用Animal.testClassMethod()

当你调用Animal.testClassMethod()时,它不能被子类的方法隐藏。

【讨论】:

    【解决方案3】:

    我认为它被称为“隐藏”,因为您不能再通过编写方法名称来访问超类的方法。没有Cat 中的public static void testClassMethod() 定义,您的main 可以说

    testClassMethod();
    

    调用Animal中定义的方法。但你不能再那样做了。是的,您仍然可以通过给它指定限定名称来调用它:

    Animal.testClassMethod();
    

    所以它没有完全隐藏。但请注意,编写语言标准的人必须为一些可能与我们在非计算世界中赋予单词的含义不太匹配的概念命名,所以有时接近是他们能做的最好的事情。你不能试图从字面上理解这个术语。我相信,hidden 这个词在 JLS 的某个地方有一个正式的定义;这意味着当您看到 JLS 中使用的术语时,它表示 JLS 定义的任何含义,不多也不少。

    【讨论】:

    • 它只是“隐藏”(有些人称之为“隐藏”),而不是“无法访问”。
    【解决方案4】:

    考虑将此添加到您发布的示例中

    class Dog extends Animal {
        // nothing here
    }
    

    现在如果你这样做:

    new Cat().testClassMethod();
    new Dog().testClassMethod();
    

    上面的每一个都会给出不同的输出。所以你可以说Cat 中的静态方法确实隐藏了Animal 的静态方法——虽然没有覆盖静态方法之类的东西,但其中一个动物是根据Animal 的代码打印的,另一个是没有。

    (P.S. 我绝对不鼓励你以这种方式调用静态方法。)

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2015-08-13
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-08-28
      • 2019-09-28
      • 2023-03-23
      • 2011-11-03
      相关资源
      最近更新 更多