鉴于此代码:
class Task{};
class TaskA extends Task{};
class TopWorker{
//... omitting constructor, instance variables, etc.
public void work(Task task){
this.subWorkerA.work(task)
//followed by more subworkers...
}
}
class SubWorkerA{
public void work(TaskA task){
// Subworker A does something interesting here
}
public void work(Task task){
// Subworker A doesn't care, do nothing
}
}
TaskA task = new TaskA();
(new TopWorker).work(task);
我希望调用TaskA
的{{1}}签名 - 而是调用work()
版本。我认为问题是Task
只接受TopWorker
,因此java必须相应地发送Task
。
有没有解决这个问题的方法?假设我有很多SubWorker.work()
和许多工人,Tasks
可以协调他们的结果。
答案 0 :(得分:1)
未调用TaskA
签名的原因是TopWorker.work
仅保证传入Task
而不传递TaskA
实例。 SubWorkerA.work(Task task)
最终被调用,因为它是唯一在参数中采用类型work
的{{1}}方法。如果您改为调用Task
,则会调用所需的方法,尽管本身就是不安全的方式。
我认为你可能会混淆使用后期绑定的方法重载。重载只是允许您以相同的方式命名方法,只要它们具有不同数量的参数或参数类型即可。当您调用重载方法时,将根据参数的组成选择正确的方法。在后期绑定中,您通过在子类中复制其签名来覆盖方法,即使您将其父对象称为超类的实例,也会强制调用重写方法。
答案 1 :(得分:1)
这是一种解决方法......
public void work(Task task){
if (task instanceof TaskA) {
work((TaskA) task);
}
// Subworker A doesn't care, do nothing
}
答案 2 :(得分:0)
我认为Task
最好是一个界面,在运行时你可以弄清楚
public void work(Task task){
if (task instanceof TaskA)
this.subWorkerA.work((TaskA) task);
}