2015-02-23 64 views
1
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必须的子类具有使用相同通用类型的管理器的构造函数。也就是说,SlotC必须有一个构造函数SlotC(Manager<SlotC> m)。从上面可以看出,SlotASlotB分别不需要SlotA(Manager<SlotA>)SlotB(Manager<SlotB>)扩展通用抽象类:正确绑定

我知道摘要Slot的构造函数不符合此要求。我如何编辑上述代码来实现这一目标?

编辑:

我知道我可以一个泛型参数T添加到Slot,使构造Slot<T>(Manager<T>)但这意味着需要SlotA<SlotA>SlotA<SlotB>是可能的。有没有比这更好的方法?

回答

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泛型在编译时未能应用限制。

+0

附加说明:这就是为什么在最常用的示例中不允许继承的原因:枚举 - 它总是最终的。 – tilois 2015-02-23 20:38:15

+0

伟大的答案,并感谢您的额外信息。这是解决方案。但是,这需要对'class Manager 进行更改。 '班级经理>'这是正确的解决办法?还是会打开任何其他通用问题? – 2015-02-23 20:40:22

+1

将其更改为'Manager >'。 – 2015-02-23 20:45:07