子方法是怎么把父方法隐藏在这里的?
正如您所说,通过定义具有相同签名的静态方法。
隐藏是如何进入画面的?
Cat.testClassMethod();
有些人可能期望在这里调用父方法(通过类比多态)。但是通过类方法隐藏的想法是不同的:
如果类 C 声明或继承静态方法 m,则称 m 隐藏任何方法 m',其中 m 的签名是 m' 签名的子签名(第 8.4.2 节),位于C 中的代码可以访问(第 6.6 节)的 C
。...
可以通过使用限定名称或使用包含关键字 super 或强制转换为 a 的方法调用表达式(第 15.12 节)来访问隐藏方法超类类型。
...
class Super {
static String greeting() { return "Goodnight"; }
String name() { return "Richard"; }
}
class Sub extends Super {
static String greeting() { return "Hello"; }
String name() { return "Dick"; }
}
class Test {
public static void main(String[] args) {
Super s = new Sub();
System.out.println(s.greeting() + ", " + s.name()); // Goodnight, Dick
}
}
JLS 10 - 8.4.8.2。隐藏(通过类方法)
这个例子完美地展示了覆盖和隐藏之间的区别。同时,这是一个不好的实践演示——在实例上调用静态方法。
我将尝试通过提供另一个示例来说明这一点。
由于继承了公共静态方法,因此以下代码段
class Animal {
public static void testClassMethod() {
System.out.println("The static method in Animal");
}
}
class Cat extends Animal {
public static void main(String[] args) {
// Cat: I don't have own method, probably I inherited it from the parent.
// O, yes. I can call it.
Cat.testClassMethod();
}
}
印刷
The static method in Animal
现在我们要添加testClassMethod
到Cat
.
class Animal {
public static void testClassMethod() {
System.out.println("The static method in Animal");
}
}
class Cat extends Animal {
public static void testClassMethod() {
System.out.println("The static method in Cat");
}
public static void main(String[] args) {
// Cat: I have two version of the method: mine and the inherited one.
// The caller specified my class name, so he wanted my version.
// I will call my method hiding the parent method.
Cat.testClassMethod();
// If he wanted Animal's version, he would write
Animal.testClassMethod();
// or (DON'T DO THIS)
((Animal)new Cat()).testClassMethod();
}
}