其他边界变通方法不能跟随类型参数

时间:2016-01-02 06:28:51

标签: java generics

那么有没有办法绕过限制,以便类DerivedA和DerivedB的方法foo可以拥有我想要的签名?

class SuperA{
}

class SuperB{
}

interface InterfaceA{

}

interface InterfaceB<T>{
    <P extends T & InterfaceA> void foo(P param);
    //error:type parameter cannot be followed by other bounds
}

class DerivedA extends SuperA implements InterfaceB<SuperA>{

    @Override
    <P extends SuperA & InterfaceA> void foo(P param){
        //P should be some type extends SuperA and implements InterfaceA.
    }
}

class DerivedB extends SuperB implements InterfaceB<SuperB>{

    @Override
    <P extends SuperB & InterfaceA> void foo(P param){
        //P should be some type extends SuperB and implements InterfaceA.
    }
}

2 个答案:

答案 0 :(得分:0)

据我所知,你想做的事情无法完成。

您需要在创建时限制T,而不是稍后

interface InterfaceB<T extends InterfaceA>{
    <P extends T> void foo(P param);
}

否则没有任何意义,编译器无法在编译时保证类型安全,这首先是泛型的目的。

没有限制T可能是Object类型没有实现您的接口,但创建具有泛型参数Object的实例不会在编译时失败,而是调用它的方法不会是Typesafe或者会在编译时失败,这没什么意义。

但这应该不是问题,您可以将需要该签名<P extends T & interface>的每个方法放入另一个InterfaceC,因为任何类都可以继承任何数量的接口,这最终将解决您的问题。 / p>

解决问题的方法可能就是这样。

class SuperA implements InterfaceA{
}

class SuperB implements InterfaceA{
}

interface InterfaceA{

}

interface InterfaceB<T extends InterfaceA>{
    <P extends T> void foo(P param);
    //error:type parameter cannot be followed by other bounds
}

class DerivedA extends SuperA implements InterfaceB<SuperA>{
    @Override
    public <P extends SuperA> void foo(P param) {
        // TODO Auto-generated method stub

    }
}

class DerivedB extends SuperB implements InterfaceB<SuperB>{
    @Override
    public <P extends SuperB> void foo(P param) {
        // TODO Auto-generated method stub

    }
}

或者您可以创建实现SuperA的{​​{1}}和SuperB的子类。

这是确保编译时类型安全的唯一方法。

答案 1 :(得分:0)

有一些解决方法,但是这些解决方法不能保证assign x_2_0_2s_compl_type1 = 3'(~x) + 1'b1; 所提供的所有保证(将来您可能会忘记并使事情变得混乱)。基本上,您只能链接上一个类型,并且只有第一个类型可以是任何组合,但是只有在声明接口时,才能在该类型上强制另一个接口。

您可以在<P extends T & InterfaceA>内添加实现InterfaceA+SuperA or InterfaceA+SuperB的子类

InterfaceB

另一种方法是,但是这种方法涉及关注为每个孩子声明的类型,但是它使继承更加稳定:

interface InterfaceB<T,T2 extends T>{ 
//T2 can only chain over T1
//but T1 can be anything, this case T1 extends Object, but it can extend any 1 Object + any multiple Interfaces 
    <T3 extends T2> void foo2(T3 param);
}

class DerivedA extends SuperA implements InterfaceB<SuperA,DerivedAWithInterfaceA>{ 
//this is kinda the only way to ensure that both SuperA+InterfaceA are used together 

    @Override
    public <T3 extends DerivedAWithInterfaceA> void foo2(T3 param) {}

}

class DerivedAWithInterfaceA extends DerivedA implements InterfaceA {
} 
//and now any SuperA+InterfaceA should extend this class instead of just SuperA
//idem class SuperB

希望这会有所帮助。