簡體   English   中英

其他邊界變通方法不能跟隨類型參數

[英]type parameter cannot be followed by other bounds workaround

那么有沒有辦法繞過限制,以便類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.
    }
}

據我所知,你想做的事情是做不到的。

您需要在創建時限制T ,而不是稍后

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

否則就沒有意義,編譯器也無法在編譯時保證類型安全,這首先是泛型的目的。

沒有限制, T可以是Object類型,它不能實現你的接口,但是在編譯時創建帶有泛型參數Object的實例不會失敗,但是調用它的方法不會是Typesafe或者在編譯時會失敗,這沒有多大意義。

但這應該不是問題,您可以將需要該簽名的每個方法<P extends T & interface>放入另一個InterfaceC ,因為任何類都可以繼承任意數量的接口,這最終將解決您的問題。

解決問題的工作方案可能就是這樣。

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

    }
}

或者您可以創建實現InterfaceBSuperASuperB子類。

這是確保編譯時類型安全的唯一方法。

有一些解決方法,但這些解決方法無法保證一切<P extends T & InterfaceA>保證(未來你可能會忘記並搞砸了一些東西)。 基本上你只能鏈接一個以前的類型,只有第一個類型可以是任何組合,但你只能在聲明接口時強制該類型的另一個接口。

你可以添加一個實現了子類InterfaceA+SuperA or InterfaceA+SuperBInterfaceB

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

另一種方法是,但這個方法涉及密切關注為每個孩子聲明的類型,但它使繼承更穩定:

class SuperA<T extends InterfaceA> implements InterfaceA{}

interface InterfaceA{}

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);
    //T3 can chain or be like T and extend over something certain like T2 extends String&InterfaceA

    //void foo3(InterfaceB<? super InterfaceA,InterfaceA> example);
    //the only time you are allowed to use super is inside methods and only ? can use them(one the left, ie ? super T is allowed but T super ? not), but again this is only chaining
}

class DerivedA<T2 extends SuperA&InterfaceA> extends SuperA implements InterfaceB<SuperA,T2>{
//here you are making sure that T2 is always parent+InterfaceA and in children DerivedAChild extends DerivedA<T2 extends DerivedA&InterfaceA> is always this+InterfaceA
    @Override
    public <T3 extends T2> void foo2(T3 param) {
    }
}

希望這可以幫助。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM