Java多态/重载意外

时间:2016-03-02 00:21:43

标签: java

鉴于此代码:

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可以协调他们的结果。

3 个答案:

答案 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);
  }