上传对象 - 静态和非静态类型的差异

时间:2015-04-02 08:29:47

标签: java casting static non-static

我有以下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。

好的,我现在删除了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输出?!?!???

4 个答案:

答案 0 :(得分:3)

这是因为这个片段:

A.anotherMethod(b)

为您提供键入A的对象。然后你打电话:

.someMethod(b)

在那个实例上。现在,看到A类不再具有someMethod(B b)方法,它将调用someMethod(A a) - 它可以做,因为B是一个子类A

因为您调用方法的实例实际上是B类型,而B类会覆盖someMethod(A a)那个最终被调用的实例,因此您的输出7。

答案 1 :(得分:0)

这是因为你首先将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。

答案 2 :(得分:0)

您无法覆盖java中的static方法。

即使你覆盖它也不会考虑或作为覆盖方法。

以下链接供您参考。

Can I override and overload static methods in Java?

答案 3 :(得分:0)

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

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; }
}

因此,我们得到了#c;'对象是B的实例,但是被转换为A.当我们在其上调用someMethod(b)时,JVM选择A.someMethod(B b)并执行其覆盖版本。如果没有呈现A.someMethod(B b),JVM会选择A.someMethod(A a)并执行其覆盖版本。