Joe*_*nte 3 java polymorphism late-binding
这段代码:
public class PMTest
{
private static class Runner { }
private static class Server extends Runner { }
private static class Task
{
public void delegate(Runner runner)
{
System.out.println("Task: " + runner.getClass().getName() +
" / " + this.getClass().getName());
}
}
private static class Action extends Task
{
public void delegate(Server server)
{
System.out.println("Action: " + server.getClass().getName() +
" / " + this.getClass().getName());
}
}
private static void foo(Task task, Runner runner)
{
task.delegate(runner);
}
private static void bar(Action task, Runner runner)
{
task.delegate(runner);
}
private static void baz(Action task, Server runner)
{
task.delegate(runner);
}
public static void main (String[] args)
{
try {
Server server = new Server();
Action action = new Action();
action.delegate(server);
foo(action, server);
bar(action, server);
baz(action, server);
}
catch (Throwable t) {
t.printStackTrace();
}
}
}
Run Code Online (Sandbox Code Playgroud)
产生这个输出:
$ java PMTest
Action: PMTest$Server / PMTest$Action
Task: PMTest$Server / PMTest$Action
Task: PMTest$Server / PMTest$Action
Action: PMTest$Server / PMTest$Action
Run Code Online (Sandbox Code Playgroud)
我可以非常清楚地看到Task的方法正在被选择而不是Action的方法.我不明白为什么,因为对象总是知道它们是什么,我认为Java的后期绑定方法选择能够区分方法签名的差异.对此的调用bar()特别令人困惑,因为在那一点上task被宣布为Action.
如果它有所作为,那就是Java 6:
$ java -version
java version "1.6.0_14"
Java(TM) SE Runtime Environment (build 1.6.0_14-b08)
BEA JRockit(R) (build R27.6.5-32_o-121899-1.6.0_14-20091001-2113-linux-ia32, compiled mode)
Run Code Online (Sandbox Code Playgroud)
我可以更改我的代码以使其工作,但我想了解它为什么不起作用.谢谢您的帮助!
这就是调度在java中的作用.
Dispatch首先基于静态参数类型,一旦选择了静态签名,则使用包含该方法的对象的运行时类型来确定使用哪个覆盖.
例如,在
void foo(Object o) {
if (o instanceof Number) { foo((Number) o); }
else if (o instanceof String) { foo((String) o); }
}
void foo(String s) { ... }
void foo(Number n) { ... }
{ foo((Object) "foo"); } // Calls foo(Object) which calls foo(String).
{ foo("foo"); } // Calls foo(String) without first calling foo(Object).
Run Code Online (Sandbox Code Playgroud)