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。它只是“隐藏”(有人称它为“阴影”),而不是“不可访问”。