class Animal { public static void staticMethod(int i) { System.out.println("Animal : static -- " + i); } public void instanceMethod(int i) { System.out.println("Animal : instance -- " + i); } } class Cat extends Animal { public static void staticMethod(int i) { System.out.println("Cat : static -- " + i); } public void instanceMethod(int i) { System.out.println("Cat : instance -- " + i); } public static void main(String[] args) { Cat myCat = new Cat(); myCat.staticMethod(1); // Cat : static -- 1 myCat.instanceMethod(2); // Cat : instance -- 2 System.out.println(""); Animal myAnimal = myCat; Animal.staticMethod(3); // Animal : static -- 3 myAnimal.staticMethod(4); // Animal : static -- 4 [ ? ] System.out.println(""); myAnimal.instanceMethod(5); // Cat : instance -- 5 } }
当我运行Cat时,我得到了以下结果:
Cat : static -- 1 Cat : instance -- 2 Animal : static -- 3 Animal : static -- 4 Cat : instance -- 5
我能理解1,2,3和5,但为什么#4不是:“Cat:static – 4”?
我的理解是这样的:
myAnimal = myCat意味着“myAnimal”现在与“myCat”完全相同,所以任何地方“myAnimal”都会出现,你可以用“myCat”替换它并获得相同的结果,因为myAnimal中的所有内容都与myCat中的所有内容相同,因此“myAnimal.staticMethod(4)”应与“myCat.staticMethod(4)”相同,输出应为:“Cat:static – 4”,类似于上面的“myCat.staticMethod(1)”.
但事实并非如此,为什么呢?
解决方法
8.4.8.2. Hiding (by Class Methods)
If a class C declares or inherits a static method m,then m is said to
hide any method m’,where the signature of m is a subsignature
(§8.4.2) of the signature of m’,in the superclasses and
superinterfaces of C that would otherwise be accessible to code in C.Example 8.4.8.2-1. Invocation of Hidden Class Methods
A class (static) method that is hidden can be invoked by using a
reference whose type is the class that actually contains the
declaration of the method. In this respect,hiding of static methods
is different from overriding of instance methods. The example:
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()); } }
produces the output:
Goodnight,Dick
because the invocation of greeting uses the type of s,namely Super,to figure out,at compile time,which class method to invoke,whereas the invocation of name uses the class of s,namely Sub,at run time,which instance method to invoke.