Java可选参数化接口

理查德:

我有一个像这样的界面:

public interface Foo<T> {
    default void doStuff(T val1, T val2) {}

    default void doStuff(T val) {}
}

接口背后的想法是您可以实现一种或其他方法。因此,我有了一个抽象类,如下所示:

abstract public class AbstractFoo<T> implements Foo<T> {
    //Bunch of Stuff
}

最后是这样的实现:

public class AwesomeOne extends AbstractFoo<String> {
    @Override
    public void doStuff(String val) {
        //Do Stuff
    }
}

这是另一个实现的示例:

public class AwesomeTwo extends AbstractFoo<String> {
    @Override
    public void doStuff(String val1, String val2) {
        //Do Stuff
    }
}

这样很好。现在,我希望能够为该doStuff(val1, val2)方法指定2种不同的类型因此,我希望能够执行以下操作:

public class AwesomeThree extends AbstractFoo<String, Double> {
    @Override
    public void doStuff(String val1, Double val2) {
        //Do Stuff
    }
}

这是我的界面将如何更改:

public interface Foo<S, T> {
    default void doStuff(S val1, T val2) {}

    default void doStuff(T val) {}
}

但是我很难让抽象类与此一起工作。因为虽然我可以将抽象类更改为:

abstract public class AbstractFoo<S, T> implements Foo<S, T> {
    //Bunch of Stuff
}

这将改变实现类,如下所示:

public class AwesomeOne extends AbstractFoo<Object, String> {
    @Override
    public void doStuff(String val) {
        //Do Stuff
    }
}

哪个可行,但是...这不是一个真正的解决方案。这也会使我重构所有现有的实现。

基本上用简单的英语我想说:

当实现Foo接口时,可以实现接口中指定的2种方法之一。如果要实现单参数方法doStuff(T val),则只需指定1个参数化类型。但是,如果要实现双参数方法doStuff(S val1,T val2),则必须指定两个参数化类型。

在Java中是否有可能,如果可以,解决此问题的最干净方法是什么?

杰夫:

您违反了一些OO原则,这就是为什么设计感觉不干净的原因。

您对实现必须执行“ this or that”的说明对我来说就像是违反了接口隔离原则。这就是SOLID原则的“ I”。

因此,要解决此问题,我们想用抽象来表示操作:

public interface StuffDoer {
  void run();
}

凉。这很简单。因此,现在您需要一个1-arg填充器和一个2-arg填充器。但是每个人都StuffDoer必须能够run()。看到?现在只是一种强制性方法。

public abstract class OneArgStuffDoer<T1> implements StuffDoer {
  private final T1 arg;
  public OneArgStuffDoer(T1 arg) {
    this.arg = Objects.requireNonNull(arg);
  }
  public final void run() {
    run(arg);
  }
  abstract void run(T1 arg);
}

您可以使用来玩类似的游戏TwoArgStuffDoer现在,您要实现的API将是扩展OneArgStuffDoerTwoArgStuffDoer,并run(T1 arg)从前者或run(T1 arg1, T2 arg2)后者实现。

如下AwesomeOne所示:

public final class AwesomeOne extends OneArgStuffDoer<String> {
  @Override
  void run(String str) { // do your awesome stuff here }
}

干净整洁!对!?!

希望有帮助!

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章