我有几个像下面这样的子控制器。我想强制开发人员根据他们的需要覆盖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 }
}
编辑:以上示例几乎解决了我的问题,但我不想在任何地方放置空方法。
答案 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();
}