1

Suppose that I have these classes:

class A {}
class B extends A {}

Also

static void call(A a) { System.out.print("A"); }
static void call(B b) { System.out.print("B"); }
public static void main(String[] args) {
    A a = new A();
    A b = new B();
    call(a);
    call(b);
}

What I am getting as output is: AA

while I was expecting: AB

I am wondering why?

4

6 回答 6

10

I am wondering why?

  • Because the reference type is A.
  • Overloaded methods are bound at compile time. So at compile time only, the compiler knows that method of class A is to be called as the type of reference variable b is A.
  • Always remember, Which overloaded method to be called is decided at compile time based on the reference type of variable

Slightly more explained,

A b = new B();

This line means that reference variable b refers to the object of class B but it is of type A and as per the rule above, the compiler knows at compile time only that the call method to be called should of class A

EDIT : as suggested by Subhrajyoti. As Subhrajyoti has rightly said, This is compile time polymorphism.

于 2013-09-11T06:33:05.800 回答
1

变量的类型bA。静态方法在变量的声明类上调用,而不是在它的实际运行时内容上调用,因此call(b)绑定为call(A b).

于 2013-09-11T06:35:04.060 回答
0

按照惯例,不建议以这种方式使用静态字段以提高可读性。如您所见,您有些困惑。

使用所有静态字段,例如“A.call(some variable)”而不是“new A().call(some variable)”。

于 2013-09-11T06:46:12.047 回答
0

重载调用绑定是在编译类型使用静态类型完成的

Java 使用静态类型引用类型来决定在编译时调用重载而不是运行时类型。

b因此,作为is的静态类型,将调用A接受参数的方法A

call(b) //Now compiler sees that reference type is A

call(A a)所以将此调用与而不是绑定 call(B b)

于 2013-09-11T06:34:17.303 回答
0

对于静态方法,您没有多态性。静态方法绑定到类。如果您有参考,A那么您可以从中调用静态方法A

于 2013-09-11T06:36:10.057 回答
0

您期望的是方法覆盖。在这种情况下,这两个调用方法应该是不同类的一部分,一个在父类中,一个在子类中,在这种情况下,两个方法签名应该完全相同/匹配。

此外,由于您的方法是静态的,因此您应该记住静态方法不会被覆盖。但是您可以在子类中编写具有相同签名和名称的静态方法,但这将被称为方法隐藏。

当您调用被覆盖的方法时,方法调用与其定义的绑定在运行时根据引用变量引用的对象类型发生。

于 2013-09-11T06:43:51.393 回答