来自docs,"如果子类定义了一个静态方法,该方法与超类中的静态方法具有相同的签名,则子类中的方法会隐藏超类中的方法。&#34 ;
我理解方法隐藏和覆盖之间的区别。但是,说子类隐藏超类方法很奇怪,因为如果你有以下内容:
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();
}
}
调用超类的静态方法。但是通过隐藏的定义,子类中的方法隐藏了超类中的方法。我不知道子类是如何"掩盖/隐藏"超类静态方法,因为超类的方法是实际调用的方法。
答案 0 :(得分:7)
调用超类的静态方法。
是。但这是因为您通过在调用语句中使用超类名称进行限定来显式命名超类的静态方法。
如果您已经写了这样的main
:
public static void main(String[] args) {
...
testClassMethod();
}
然后您会看到Cat
版本的testClassMethod
被调用。这里,Cat.testClassMethod
方法隐藏了Animal.testClassMethod
方法
答案 1 :(得分:2)
Cat
' testClassMethod()
隐藏Animal.testClassMethod()
,因为如果您在testClassMethod()
课程中没有静态Cat
, Cat.testClassMethod()
会调用Animal.testClassMethod()
。
当您致电Animal.testClassMethod()
时,它无法通过子类的方法隐藏。
答案 2 :(得分:0)
考虑将此添加到您发布的示例
class Dog extends Animal {
// nothing here
}
现在,如果你这样做:
new Cat().testClassMethod();
new Dog().testClassMethod();
以上各项都会给出不同的输出。所以你可以说Cat
中的静态方法确实隐藏了Animal
的静态方法 - 虽然没有覆盖静态方法的东西,其中一个动物打印出来根据{{1}}的代码而另一个没有。
(P.S。我绝对不鼓励你以这种方式调用静态方法。)
答案 3 :(得分:0)
我认为它被称为"隐藏"因为你不能再仅仅通过编写方法名来访问超类的方法了。如果public static void testClassMethod()
中没有Cat
定义,则main
可以说
testClassMethod();
调用Animal
中定义的方法。但你不能再这样做了。是的,你仍然可以给它一个合格的名字来打电话:
Animal.testClassMethod();
所以它完全隐藏了。但是请注意,编写语言标准的人必须为某些概念提出名称,这些概念可能与我们在非计算世界中给出的含义不完全相符,所以有时候接近他们能做的最好。你不能尝试从字面上理解术语。我认为,hidden
这个词在JLS的某个地方有一个正式的定义;这意味着当你看到JLS中使用的术语时,它意味着JLS定义它的意思,无论是更多还是更少。