Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/331.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/oop/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 为什么它被称为;方法隐藏";?_Java_Oop_Inheritance_Polymorphism_Dynamic Binding - Fatal编程技术网

Java 为什么它被称为;方法隐藏";?

Java 为什么它被称为;方法隐藏";?,java,oop,inheritance,polymorphism,dynamic-binding,Java,Oop,Inheritance,Polymorphism,Dynamic Binding,“如果子类定义的静态方法与超类中的静态方法具有相同的签名,则子类中的方法将隐藏超类中的方法。” 我理解方法隐藏和重写之间的区别。但是,说子类隐藏了超类方法是很奇怪的,因为如果您有以下内容: public class Cat extends Animal { public static void testClassMethod() { System.out.println("The static method in Cat"); } public void

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

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

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
testClassMethod()
隐藏
Animal.testClassMethod()
,因为如果
Cat
类中没有静态的
testClassMethod()
,那么
Cat.testClassMethod()
将调用
Animal.testClassMethod()

调用
Animal.testClassMethod()
时,子类的方法无法隐藏它

调用超类的静态方法

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

如果您编写的
main
是这样的:

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

然后您会看到调用了
testClassMethod
Cat
版本。这里,
Cat.testClassMethod
方法隐藏了
Animal.testClassMethod
method

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

class Dog extends Animal {
    // nothing here
}
现在,如果您这样做:

new Cat().testClassMethod();
new Dog().testClassMethod();
以上每一项都将给出不同的输出。所以你可以说猫的静态方法确实隐藏了动物的静态方法——虽然静态方法没有覆盖,但是其中一个动物是根据动物的代码打印的,而另一个没有

(顺便说一句,我绝对不鼓励您以这种方式调用静态方法。)

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

testClassMethod();
调用
Animal
中定义的方法。但你不能再这样做了。是的,您仍然可以通过给它起限定名来调用它:

Animal.testClassMethod();

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

而“明确命名事物”正是人们绕过隐藏事物的方式。例如
Animal.testClassMethod
this.value=value
OuterClass.this.method()
。我认为这类似于局部变量隐藏字段的方式。该字段仍然是可访问的(就像超类的静态方法一样),但它是隐藏的(使访问变得更加困难),因为Cat.staticMehodName()的行为是调用Cat而不是Animal。它只是“隐藏”(有人称它为“阴影”),而不是“不可访问”。