Java对象赋值是什么意思?

Fra*_*ank 6 java object variable-assignment

我有以下两个班级:

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
    }
} 
Run Code Online (Sandbox Code Playgroud)

当我运行Cat时,我得到了以下结果:

Cat : static -- 1
Cat : instance -- 2

Animal : static -- 3
Animal : static -- 4

Cat : instance -- 5
Run Code Online (Sandbox Code Playgroud)

我能理解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)".

但事实并非如此,为什么呢?

Ale*_*yuk 2

来自Oracle 文档

\n\n
\n

8.4.8.2. 隐藏(通过类方法)

\n\n

如果类 C 声明或继承静态方法 m,则称 m 隐藏任何方法 m\',其中 m 的签名是 m\ 签名的子签名\n (\xc2\xa78.4.2) ',在 C 的超类和超接口中,否则 C 中的代码可以访问它们。

\n\n

示例 8.4.8.2-1。隐藏类方法的调用

\n\n

隐藏的类(静态)方法可以通过使用引用来调用,该引用的类型是实际包含该方法声明的类。在这方面,静态方法的隐藏与实例方法的重写不同。这个例子:

\n
\n\n
class Super {\n            static String greeting() { return "Goodnight"; }\n            String name() { return "Richard"; }\n        }\n        class Sub extends Super {\n            static String greeting() { return "Hello"; }\n            String name() { return "Dick"; }\n        }\n        class Test {\n            public static void main(String[] args) {\n                Super s = new Sub();\n                System.out.println(s.greeting() + ", " + s.name());\n            }\n        }\n
Run Code Online (Sandbox Code Playgroud)\n\n
\n

产生输出:

\n\n

晚安,迪克

\n\n

因为greeting的调用使用s的类型,即Super,\n来在编译时确定要调用哪个类方法,而name的调用使用s的类,即Sub,来确定, \n 在运行时,要调用哪个实例方法。

\n
\n