如何用不同的参数覆盖方法?

时间:2017-09-29 13:01:20

标签: java

我有几个像下面这样的子控制器。我想强制开发人员根据他们的需要覆盖run方法。我的意思是扩展MainController的所有类都必须覆盖run()或run(String command)方法。有没有办法做到这一点?

我有一个名为MainController的基类

public abstract class MainController{
   public abstract void run();
   public abstract void run(String command);
}

public class Sub1Controller extends MainController{
   public void run(){  //Some Codes Here  }
   public void run(String command) {}  //empty method here
}

public class Sub2Controller extends MainController{
   public void run(){} //empty method here
   public void run(String command) {  //Some Codes Here  }
}

编辑:以上示例几乎解决了我的问题,但我不想在任何地方放置空方法。

2 个答案:

答案 0 :(得分:2)

您不能强迫开发人员实现一个抽象方法,而不必实现其他方法。您可以提供空的默认实现,并在需要时让dev覆盖:

//making the class abstract forces the dev to subclass it but not to override any method,
//which might not be necessary anyways.
public abstract class MainController{
  public void run() { }
  public void run(String command) {}
}

public class Sub1Controller extends MainController{
  @Override
  public void run(){  /*override only this method*/  }
}

强制开发人员只覆盖一个方法而不是另一个方法根本不可能。问题是每个具体类都需要实现每个方法,因此你来提供实现 - 通过默认提供它们或强迫开发人员提供它们,即使它们不需要也是如此。 / p>

然而,你的问题表明了一个设计缺陷:如果开发人员只需要实现其中一种方法,你将如何确保覆盖正确的那个(被调用的那个)?理论上你可以同时调用这两种方法,但是如何阻止开发提供/覆盖这两种方法的实现?

因此,不同的设计可能更适合。虽然在不了解更多背景的情况下提出一个很难。一种方法可能是只提供一个方法,该方法接受表示所有可能参数的参数对象,并让dev决定使用哪些参数。另一种选择可能是使用多个接口(每个接口包含一个方法)并让dev实现这些接口(尽管它们仍然可以在同一个类中实现多个接口)。

使用泛型的选项1(仅一种方法)的示例:

public interface Command {}

public interface MainController<T extends Command> {
  public void run( T command );
}

public class Sub1Command implements Command { ... }

public class Sub1Controller implements MainController<Sub1Command> {
  public void run( Sub1Command command ) { ... }
}

在示例中,我使用泛型来定义传递的命令参数的类型。因此,实现可以定义run()方法应该接受哪种类型的命令(调用可能稍微复杂一些,但同样缺少上下文)。

要支持类似于run()的方法,您可以提供一个空实现,例如VoidCommand implements Command,然后Sub2Controller implements MainController<VoidCommand>

答案 1 :(得分:0)

问题是:为什么在界面中需要该方法的两个版本?

我怀疑这是对易用性的错误理解。

更方便的解决方案是为不需要命令的情况提供特殊的NO_COMMAD常量:

 public interface MyInterface {
    public static final String NO_COMMAD = "";
    public void run(String command);
}

这解决了您使用替代方法签名的问题。

甚至可能是创建不同的接口,其中一个参数在方法签名中而另一个没有:

 public interface MyInterfaceWithParam {
    public void run(String command);
}

 public interface MyInterfaceWithoutParam {
    public void run();
}