具有不同返回类型的通用接口[Java]

时间:2017-05-02 14:29:00

标签: java design-patterns interface

我尝试通过扩展/实现包含单个方法Command的{​​{1}}类来尝试在各种类中实现Command模式。但是,我注意到我需要实现模式的多种变体,以允许它返回不同的值,例如public void execute()和其他自定义值。我希望所有这些类继承/实现一个公共接口,要求它们实现方法execute()(可能还有其他几种方法),同时为每个类提供添加自己的返回类型的灵活性。

首先,我认为我可以使用泛型来完成此操作,但这不起作用 - 因为它不会在子类中强制执行返回类型(它允许任何返回类型)。

技术,我可以创造许多" Command"类(例如boolean + BooleanCommand +其他几个具有自定义返回类型的类)但这意味着我需要从头开始设计每个类,因为它们没有实现公共接口。换句话说,我无法让StringCommand实现基类BooleanCommand,从而迫使它实现方法Command,同时允许它拥有它[&1;}自己的返回值execute()。同样,我希望boolean类实现基类StringCommand(从而强制它实现方法Command),同时允许它execute()作为返回值

如果我在每个类中只有一个方法,但如果我有多个方法并且没有办法强制执行此设计,那么这可能没问题?

如何解决此设计问题?

3 个答案:

答案 0 :(得分:1)

执行不应返回值。检查命令/查询分离的概念。 如果你真的决定拥有一个返回对象,那么你应该将返回对象封装在一个类中,然后可以调用getBooleanValue getStringValue

答案 1 :(得分:1)

您可以使用泛型来实现类来定义返回类型:

interface Command<R> {
  R execute();
  R evaluateCommandSuccess();
  R logBefore();
}

interface BooleanCommand extends Command<Boolean> {}
interface StringCommand extends Command<String> {}
interface VoidCommand extends Command<Void> {}

class BooleanCommandImpl implements BooleanCommand {
  @Override public Boolean execute() {
    return true;
  }

  @Override public Boolean evaluateCommandSuccess() {
    return true;
  }

  @Override public Boolean logBefore() {
    return true;
  }
}

class StringCommandImpl implements StringCommand {
  @Override public String execute() {
    return "STRING";
  }

  @Override public String evaluateCommandSuccess() {
    return "STRING";
  }

  @Override public String logBefore() {
    return "STRING";
  }
}

class VoidCommandImpl implements VoidCommand {
  @Override public Void execute() {
    return null;
  }

  @Override public Void evaluateCommandSuccess() {
    return null;
  }

  @Override public Void logBefore() {
    return null;
  }
}

但是,正如您所看到的,XYZCommand接口实际上是空的; XYZCommandCommand<XYZ>之间没有任何有意义的区别:这几乎就是泛型的用途。

答案 2 :(得分:0)

如果您正在尝试实施以下内容

class Command {
   execute() {...}
}

class BooleanCommand extend Command  {
   execute() {...; return True;}
}

class StringCommand extend Command  {
   execute() {...; return "STRING";}
}

然后,Java 5+中的'covariant return type'是可能的。 'Covariant return' - 表示当一个覆盖方法时,覆盖方法的返回类型被允许为被覆盖方法的返回类型的子类型。很少有关于它的相关讨论herehere

在您的情况下,我们可以为您提供以下定义

class Command {
   public Object execute() {...; return Null;}
}

class BooleanCommand extend Command  {
   public Boolean execute() {...; return True;}
}

class StringCommand extend Command  {
   public String execute() {...; return "STRING";}
}

接口也可以观察到相同的行为。您可以执行类似的操作并强制您实现BooleanCommand和StringCommand的子类以返回其特定的返回类型。

interface Command {
    public Object execute();
}

interface BooleanCommand extends Command {
    public Boolean execute();
}

interface StringCommand extends Command {
    public String execute();
}

希望它有所帮助!