编写指向其实现者的通用接口的便捷方式

时间:2013-04-15 18:39:18

标签: java generics

java中是否有一种编写通用接口的方法,以更方便的方式指出这种接口的实现者?

例如我写了界面:

public interface Updatable<T> {
    void updateData(T t);
}

我想指出只有实现者的实例可以在updateData(T t)方法中传递。

所以,我必须写下这样的东西:

public class Office implements Updatable<Office> {

@Override
    public void updateData(Office office) {
        //To change body of implemented methods use File | Settings | File Templates.
    }
...
...
...
}

但似乎有点难看。你有更好的变种吗?

3 个答案:

答案 0 :(得分:3)

人们一直在要求“这种”类型,主要是为了流畅的API。它可能永远不会成功。但我认为建立一个约定是可以的 - 命名类型变量This来表示this的类型。所以读者看到This并确切知道它应该是什么;滥用不太可能

public interface Updatable<This> {
    void updateData(This t);
}

// any Foo implementing Updatable must supply This=Foo

public class Office implements Updatable<Office> 

由于This必须是Updatable<This>的子类型,人们通常会表达这种约束

public interface Updatable<This extends Updatable<This>> 

我认为没有必要,也不应该这样做。 This的命名惯例已经足够了。

这种限制措施不够严格,以防止误用。例如

public interface Foo<T extends Foo<T>>

public class Foo1 implements Foo<Foo1>  // good, intended use

public class Foo2 implements Foo<Foo1>  // compiles! but not intended

答案 1 :(得分:3)

这很好,并且是最不丑陋的方式和最清晰的方法。

泛型只是为了确保类型安全,即避免演员表。您的Updatable界面已经完全是类型安全的。那为什么要改变什么?

  

我想指出只能传入实现者的实例   updateData(T t)方法。

关键问题是:为什么你想这样做?我没有看到任何类型安全的原因,因为查看界面本身为什么需要这样做。

如果Office类要求其updateData方法的参数为Office,那很好。但这将是Office类特有的要求,因此Office应该负责(并且在您的代码中)用于实现具有适当类型参数的接口。

答案 2 :(得分:1)

我会写

public interface Updatable<T extends Updatable<?>> {
    void updateData(T t);
}

同样难看,但更明确T必须实现接口。