扩展通用抽象类:正确的边界

时间:2015-02-23 20:22:01

标签: java generics abstract

public class GenericTest {

    public static void main(String[] args) {
        Manager<SlotA> mA = new Manager<SlotA>();
    }

}

class Manager<SlotClass extends Slot> {

}

abstract class Slot {
    public Slot(Manager<? extends Slot> m) {

    }
}

class SlotA extends Slot {

    public SlotA(Manager<SlotB> m) { //a constructor with Manager<SlotA> is not required!
        super(m);
    }
}

class SlotB extends Slot {

    public SlotB(Manager<SlotA> m) { //a constructor with Manager<SlotB> is not required!
        super(m);
    }

}

上面是代码,它模拟了我想要克服的问题。我的目标是强制Slot 必须的子类具有使用相同泛型类型的Manager的构造函数。也就是说,SlotC必须有一个构造函数SlotC(Manager<SlotC> m)。如上所示,SlotASlotB分别不需要SlotA(Manager<SlotA>)SlotB(Manager<SlotB>)

我知道抽象Slot的构造函数不符合此要求。如何编辑上述代码才能实现此目的?

修改

我知道我可以向T添加通用参数Slot并制作构造函数Slot<T>(Manager<T>)但这意味着需要SlotA<SlotA>并且SlotA<SlotB>是可能的。还有比这更好的方法吗?

1 个答案:

答案 0 :(得分:3)

您必须使用自引用类型参数使Slot类具有通用性:

abstract class Slot<T extends Slot<T>> {
    public Slot(Manager<T> m) {

    }
}

class SlotA extends Slot<SlotA> {

    public SlotA(Manager<SlotA> m) { //a constructor with Manager<SlotA> is not required!
        super(m);
    }
}

class SlotB extends Slot<SlotB> {

    public SlotB(Manager<SlotB> m) { //a constructor with Manager<SlotB> is not required!
        super(m);
    }
}

现在,您的SlotA构造函数只能有Manager<SlotA>

但是,这并不限制某人创建类似的类:

class SlotC extends Slot<SlotA> { }

你无法避免这种情况。这是一个这样的领域,Java泛型无法在编译时应用限制。