1

我正在考虑对接口而不是具体类进行编程,但我有一个疑问:任何接口方法都应该能够保存对具体类的引用吗?

假设以下场景:

1)

public interface AbsType1 {
    public boolean method1(int a); // it's ok, only primitive types here
}

2)

public interface AbsType2 {
    public boolean method2(MyClass a); // I think I have some coupling here
}

我应该在这里选择不同的设计以避免后者吗?例如

public interface MyInterface {} // yes, this is empty

public classe MyClass implements MyInterface {
    // basically identical to the previous "MyClass"
}


public interface AbsType2 {
    public boolean method2(MyInterface a); // this is better (as long as the
                                           // interface is really stable)
}

但是仍然有一些事情不能说服我......我对声明一个空接口感到不舒服,尽管我看到其他人这样做。也许抽象类在这里会更好用?

我有点困惑。

编辑:

好的,我将尝试通过举例来更具体。假设我正在设计一个 ShopCart,我当然想将商品添加到购物车:

public interface ShopCart {
    public void addArticle(Article a);
}

现在,如果 Article 是一个具体的类,如果它的实现随时间发生变化怎么办?这就是为什么我可以考虑将其设为接口的原因,但话又说回来,它可能至少在语义层面上不合适,因为接口应该指定行为而文章没有(或几乎没有......我猜它是一种实体班级)。

所以,我现在可能最终得出的结论是,在这种情况下,让 Article 成为一个抽象类将是最好的事情......你怎么看?

4

3 回答 3

2

我会使用接口,因为组合比继承要好得多。“任何接口方法都应该能够保存对具体类的引用吗?”,为什么不应该呢?包中的一些类是耦合的,这是一个事实和常用的技术。当您在接口中标记此关系时,您会看到哪些类依赖于您的实现。依赖或组合关系不是继承,因此 ai 会避免抽象类。

于 2014-04-14T11:19:29.860 回答
1

在我看来Interfaces,适用于实现可能会有所不同的所有类型。但是,如果您定义 amodule引入了一种新类型,并且不打算具有替代实现,那么首先不需要将其定义为 a Interface。在我看来,这通常是过度设计。它取决于问题域,并且通常取决于支持测试或 AOP 编织的方式。

例如,考虑一个需要将 a 建模Location为类型的 2D 问题域。如果很清楚 aLocation始终由 axy坐标表示,您可以将其提供为 a Class。但是,如果您不知道 aLocation可能具有哪些属性(GPS 数据、x、y、z 坐标等),但您依赖于某些行为,例如distance(),则应该将其建模为接口。

于 2014-04-14T11:16:39.467 回答
1

如果没有AbsType可以访问的公共方法,MyClass那么空接口可能不是一个好方法。

静态方法没有接口声明(契约),否则在这里可能有意义。

所以,如果AbsType不打算使用MyClass/MyInterface的任何方法,那么我认为它基本上只是为了其他目的而存储类对象。在这种情况下,请考虑使用泛型来明确您希望如何AbsType使用而不与客户端代码紧密耦合,例如

public class AbsType3<C extends Class<?>> {

  public boolean method3(T classType) {...}

}

<C extends Class<?>>然后,您可以通过将类型参数交换为也可能是接口的其他东西 来限制类的类型以在需要时允许,例如<C extends Class<Collection<?>>>.

空接口有点像类的布尔标志:一个类实现接口(true)或者不实现接口(false)。如果有的话,应该使用这些标记接口来传达关于如何使用(或不使用)类的重要声明,Serializable例如,请参见。

于 2014-04-14T11:23:54.927 回答