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)
- 它可以这样做,因为 B
是A
.
的子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) 并执行其覆盖版本。
我有以下 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)
- 它可以这样做,因为 B
是A
.
因为您调用该方法的实例实际上是 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) 并执行其覆盖版本。