接口方法采用相同的接口实现

时间:2016-03-30 20:29:55

标签: java

我有以下界面:

public interface ClusterPopulation
{
    public double computeDistance(ClusterPopulation other);
}

是否可以在接口本身中指定,ClusterPopulation的实现A只能将A实现作为computeDistance的参数?

我看到的唯一的approching解决方案如下,但我不喜欢它:

使用泛型重新定义界面:

public interface ClusterPopulation
{
    public <T extends ClusterPopulation> double computeDistance(T other);
}

在实现中,如果参数不是良好类型,则抛出IllegalArgumentException,如果类型正常,则执行一些强制转换... Meeeeh!

即使采用这种方法,最终用户也只是通过阅读文档/查看代码实现/试验和错误来了解约束...

有更好的解决方案吗?

2 个答案:

答案 0 :(得分:5)

您对使用泛型有正确的想法,但不是将其应用于方法,而是将其应用于整个界面。

public interface ClusterPopulation<T extends ClusterPopulation<T>>
{
    double computeDistance(T other);
}

这允许实现将T定义为自身。

public class ClusterPopulationA implements ClusterPopulation<ClusterPopulationA> {  // ...

但是,它并不禁止实现将其定义为其他内容。

public class BreaksPattern implements ClusterPopulation<ClusterPopulationA>

在您的文档中包含所有子类应将类型参数T定义为自己的类。

答案 1 :(得分:0)

在我看来,您的设计存在一个导致问题的缺陷。根据您提供的内容,似乎ClusterPopulation应该是一个类,而不是一个接口。让我们看看这个方法,

public double computeDistance(ClusterPopulation other);

这是什么意思?这意味着将ClusterPopulation类型的对象传递给此方法。此外,此对象必须具有一些属性,否则如果不是这样,您将如何计算与该对象的距离?结合这两个观察结果,可以得出结论,ClusterPopulation应该是一个类,以便拥有该类型的对象。当我说一堂课时,它可以是具体的或抽象的。让我们以抽象类为例。

public abstract class ClusterPopulation
{
    // common attributes, if any

    abstract public double computeDistance();
}

public class A extends ClusterPopulation {

    public double computeDistance() {
        // do some computation based on ClusterPopulation attributes

    }

}

public class B extends ClusterPopulation {

     public double computeDistance() {
        // do computation based on ClusterPopulation attributes

     }

}

现在,您可以这样使用它:

ClusterPopulation a = new A();
ClusterPopulation b = new B();

double aResult = a.computeDistance();
double bResult = b.computeDistance();

请注意,此处强制执行您所需的限制。虽然 a b 都是ClusterPopulation类型的对象,但 computeDistance()仅适用于调用对象的具体类型。