Upcasting Objects - 静态和非静态类型的区别

Upcasting Objects - difference of static and non-static type

我有以下 java 代码:

class A {
 int someMethod () { return 1; }
 int someMethod (A a) { return 2; }
 int someMethod (B b) { return 3; }
 int someMethod (C c) { return 4; }
 static A anotherMethod ( Object obj) { return (A) obj; }
 }

class B extends A {
 int someMethod () { return 6; }
 int someMethod (A a) { return 7; }
 int someMethod (B b) { return 8; }
 int someMethod (C c) { return 9; }
 static A anotherMethod ( Object obj) { return (B) obj; }
 }

 class C extends A {
 int someMethod () { return 11; }
 int someMethod (A a) { return 12; }
 int someMethod (B b) { return 13; }
 int someMethod (C c) { return 14; }
 static C anotherMethod ( Object obj) { return (C) obj; }
 }

public static void main ( String [] args ){
 A a = new A(); B b = new B(); C c = new C();
 System .out. println (A. anotherMethod (b). someMethod (b));
}

正如预期的那样,输出是 8。

好的,现在我删除 class A:

中的 someMethod(B b)
class A {
 int someMethod () { return 1; }
 int someMethod (A a) { return 2; }
 int someMethod (C c) { return 4; }
 static A anotherMethod ( Object obj) { return (A) obj; }
}

我和我的朋友讨论了输出,但没有人能准确解释为什么我们现在得到 7 作为输出?!?!???

这是因为您首先将 B 对象转换为 A,然后在名为 b 的变量中有一个类型 A 的引用,当您将 b 传递给该方法时,您真正传递的是对 A 的引用。

A.anotherMethod (b) // Casts and returns a reference of type A. 
.someMethod(b) // What you really have here is a reference of type A 

所以这将调用 someMethod(A a) 并因此将输出 7.

发生这种情况是因为这个片段:

A.anotherMethod(b)

给你一个类型为 A 的对象。然后你打电话:

.someMethod(b)

在那个实例上。现在,由于 A class 不再有 someMethod(B b) 方法,它将改为调用 someMethod(A a) - 它可以这样做,因为 BA.

的子class

因为您调用该方法的实例实际上是 B 类型,并且 B class 覆盖最终被调用的 someMethod(A a),因此你的输出为 7.

您不能覆盖 java 中的 static 方法。

即使您覆盖了也不会考虑或作为覆盖方法工作。

以下link供您参考。

Can I override and overload static methods in Java?

如果以更简单的方式编写相同场景的代码,那么一切都会变得清晰:

public class Playground {

public static void main(String[] args) throws Exception {
    B b = new B();
    A casted = (A) b;
    System.out.println(casted.someMethod(b));
}

}

class A {
int someMethod(A a) { return 2; }
int someMethod(B b) { return 3; }
}

class B extends A {
int someMethod(A a) { return 7; }
int someMethod(B b) { return 8; }
}

因此,我们得到了 'casted' 对象,它是 B 的实例,但被转换为 A。当我们在其上调用 someMethod(b) 时,JVM 获取 A.someMethod(B b) 并执行它的覆盖版本。如果 A.someMethod(B b) 未出现,JVM 将选择 A.someMethod(A a) 并执行其覆盖版本。