【问题标题】:Problem with multiple classes implements same interface多个类实现相同接口的问题
【发布时间】:2021-10-18 19:18:59
【问题描述】:

我无法理解多个类何时实现相同的接口,在我使用具体类作为 DI 之前,但在搜索和阅读之后,我被告知它应该取决于抽象。所以这是我的问题:

interface SomeInterface{
    public void doSomething();
}

我们有两个实现接口的类:

class FirstClass implements SomeInterface{

    @Override
    public void doSomething(){
        System.out.print("First class is doing something");
    }
}

class SecondClass implements SomeInterface {

    @Override
    public void doSomething() {
        System.out.print("Second class is doing something");
    }
}

现在我有一个客户,我想使用第一类和第二类的方法:

class ClientClass {
    private SomeInterface someInterface;
  
    public ClientClass(SomeInterface someInterface) {
        this.someInterface = someInterface;
    }

    public void testMethod() {
        this.someInterface.doSomething();
    }
}

现在,当我实例化客户端类时,我只能在第一个或第二个构造函数中传递一个类,并且该方法将启动,但如果我想要两种方法怎么办?这个设计有什么问题?

【问题讨论】:

  • 我相信答案很大程度上取决于您的模型。在某些情况下,最好创建几个单独的ClientClass 实例并独立调用testMethods,或者在其他情况下使用Composite 之类的设计模式
  • 这个设计有什么问题? - 它本身并没有错,只是它一次可以处理一个SomeInterface。如果您只需要其中两个,则可以使用 2 个成员变量,并在构造函数中期望 2 个参数。但是,如果您需要任何数量的它们,一些ListSet 可能是更好的方法,稍后您可能还需要在构造函数之外更改SomeInterfaces 的集合。
  • 让它更清晰。想象一下你的ClientClass 实际上是DatabaseConnector。您是否希望该类使用 Mysql 类和 Postgres 类中的方法连接到数据库?

标签: java oop interface abstraction


【解决方案1】:

您可以使用这两种方法,但不能同时使用(除非您构建另一个实现来让您进行复合实现)。

例如,您可以使用SomeInterface 的不同实现来拥有ClientClass 的不同实例:

ClientClass clA = new ClientClass(new FirstClass());
ClientClass clB = new ClientClass(new SecondClass());

现在您有两个对象,clAclB,它们具有相同的类型,但行为不同,因为它们包含了不同的 SomeInterface 实例。

当您将 DI(依赖注入)添加到图片时,您可以编写生成 ClientClass 实例的代码,它不知道 FirstClassSecondClass,这样您就可以保留客户端实现独立于SomeInterface 层次结构。

【讨论】:

  • 感谢您花时间写答案,但这并没有解决我的问题,我只能拥有一个 Client 类的实例。我应该为这两个类有两个单独的接口吗?或者也许是一些列表?你会如何解决这个问题?
【解决方案2】:

接口的至少两个优点是 1) 为实现类的tie together 提供可以由多个类实现的抽象方法,以及 2) 允许这些接口的机制其他的可以由同一个类实现(而不是单一的继承模型)。

如果您的不同类具有相同的含义和返回类型,我认为没有理由不能全部实现相同的接口。也可以实现其他接口(并且接口可以扩展其他接口)。

如果每个类使用不同的接口,那么强烈建议根据需要创建一个新接口。否则你的代码会让未来的维护者非常困惑。如果按如下所述使用它也可能无意中导致问题(这是共享接口的典型情况)。

但是想象一下需要getTotal() 方法的五个不同类的列表。声明一个名为Results 的接口并让这些类实现它。然后每个实例都可以放在一个List<Results> 中,然后可以通过调用getTotal() 方法的每个引用进行迭代。

【讨论】:

    猜你喜欢
    • 2014-10-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-08-18
    • 1970-01-01
    • 2019-04-08
    • 1970-01-01
    • 2013-07-03
    相关资源
    最近更新 更多