java static binding,Java静态和动态绑定,重载

I am practicing for a test and I came across this exercise about overloading and static and dynamic binding. The output of the following code is asked:

class Moe {

public void print(Moe p) {

System.out.println("Moe 1");

}

}

class Larry extends Moe {

public void print(Moe p) {

System.out.println("Larry 1");

}

public void print(Larry l) {

System.out.println("Larry 2");

}

}

class Curly extends Larry {

public void print(Moe p) {

System.out.println("Curly 1");

}

public void print(Larry l) {

System.out.println("Curly 2");

}

public void print(Curly b) {

System.out.println("Curly 3");

}

}

class Overloading {

public static void main (String [] args) {

Larry stooge1 = new Curly();

Moe stooge2 = new Larry();

Moe stooge3 = new Curly();

Curly stooge4 = new Curly();

Larry stooge5 = new Larry();

stooge1.print(new Moe());

stooge1.print(new Curly());

stooge1.print(new Larry());

stooge2.print(new Curly());

stooge3.print(new Curly());

stooge3.print(new Larry());

stooge5.print(new Curly());

}

}

I think I get the first one but on the others I am completely lost. This is how I solved the first one:

at runtime the type of stooge1 is Curly, so we're calling the print method of Curly. Because we pass an object of type Moe to print, the corresponding print method with argument type Moe is run in Curly. The output of this method is Curly 1, the correct answer.

However, when I apply this technique to the following lines I end up with the wrong answers. Can someone explain me how exactly this concept works in Java?

The correct output of the code is:

Curly 1

Curly 2

Curly 2

Larry 1

Curly 1

Curly 1

Larry 2

解决方案

Static binding happens at compilation time and dynamic binding at runtime.

Static binding is responsible for selecting signature (name and argument types) of method which should be executed. It uses

name of method

type of variables holding arguments (compiler doesn't assume what actual object variable will hold at runtime, he picks signature which will be able to handle all of possible cases).

Compiler selects signature from variable type on which method is invoked, so Object o = "abc"; will not allow you to invoke o.substring(1,2); because compiler will not be able to find substring(int, int) signature in Object class (which is type of o variable on which substring method was invoked).

Dynamic binding is responsible for finding and invoking code of method selected by static binding at compilation time. It will try to find code of method in type of actual instance held by variable. In other words if you have Animal a = new Cat(); a.makeSound(); you can expect to get as result "Mew" because at runtime JVM will search and invoke code of makeSound starting from Cat class. If implementation will not be provided in that class JVM will search for it in ancestor(s) until it finds one from which it was inherited.

I renamed classes and variables in your example a little to hopefully make it more readable:

class A {

public void print(A a) {

System.out.println("A.print(A)");

}

}

class B extends A {

public void print(A a) {

System.out.println("B.print(A)");

}

public void print(B b) {

System.out.println("B.print(B)");

}

}

class C extends B {

public void print(A a) {

System.out.println("C.print(A)");

}

public void print(B b) {

System.out.println("C.print(B)");

}

public void print(C c) {

System.out.println("C.print(C)");

}

}

class OverloadingDemo {

public static void main (String [] args) {

A ab = new B();

A ac = new C();

B bb = new B();

B bc = new C();

bc.print(new A());

bc.print(new C());

bc.print(new B());

ab.print(new C());

ac.print(new C());

ac.print(new B());

bb.print(new C());

}

}

(variable naming -> variable of type X holding instance of type Y is named xy).

So, when we execute

bc.print(new A());

static binding will try to find best print method signature available in class B which can handle instance of type A. In this case it will be print(A).

after that dynamic binding will search for code of this method in class C (since this is type of instance held by bc variable) which means we will see C.print(A).

Similarly in case of bc.print(new C());

static binding will try to find best print method for C argument available in B class, which for C is print(B) (since there is no print(C) there and B is closest supertype).

So now dynamic binding knows which method to look for in C class (since this is instance which bc holds).

So it will invoke C.print(B).

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值