[英]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
}
}
或者您可以創建實現InterfaceB
的SuperA
和SuperB
子類。
這是確保編譯時類型安全的唯一方法。
有一些解決方法,但這些解決方法無法保證一切<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
另一種方法是,但這個方法涉及密切關注為每個孩子聲明的類型,但它使繼承更穩定:
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.