java泛型类扩展了泛型参数

时间:2016-11-06 15:46:11

标签: java templates generics

简短版本:

使类扩展其泛型参数的正确语法是什么:

 class A<T> extends T {} // doesn't compile

长版:

我有一个基本的抽象类(以下代码只是为了这个帖子而缩短了)

abstract class D { 
     abstract void f();
     abstract void g();
}

然后,每个f()和每个g()都有一组可能的组合。目标是拥有所有可能的组合。

一种解决方案是为每个f_j()创建一个扩展D的类Fj并实现f_j(),然后对于每个g_i(),我们创建一个扩展Fj并实现g_i()的类GiFj。 例如

abstract class F1 extends D {
    @Override
    void f() { /* F1 Work */ }
}
abstract class F2 extends D {
    @Override
    void f() { /* F2 Work */ }
}
class G1F1 extends F1 {
    @Override
    void g() { /* G1 Work */ }
}
class G1F2 extends F2 {
    @Override
    void g() { /* G1 Work : Duplicated Code */ }
}

问题是Gi的代码会多次重复。

我想要实现的解决方案是将所有GFi重组为通用类

class G1<F extends D> extends F {
    @Override
    void g() { /* G1 work */ }
}

那么如何在java中做到这一点,或者如果不可能做到这一点的好方法

1 个答案:

答案 0 :(得分:1)

回答简短版

这在Java中是不可能的。编译器需要在编译时知道类的超类具有哪些方法和字段。因此,类只能扩展具体类(可能使用类型变量),但它不能自己扩展类型变量。

回答长版本(表面上似乎与短版本无关)

您可以使用合成来实现您想要的类型:

class Foo {
    final FDelegate fDelegate;
    final GDelegate gDelegate;

    Foo(FDelegate fDelegate, Delegate gDelegate) {
        this.fDelegate = fDelegate;
        this.gDelegate = gDelegate;
    }

    void f() {
        fDelegate.f(this);
    }

    void g() {
        gDelegate.g(this);
    }
}

interface FDelegate {
    void f(Foo container);
}
interface GDelegate {
    void g(Foo container);
}

然后您有包含各种方法实现的类F1F2G1G2。您传递Foo对象,以便可以访问其(可见)成员。