使用扩展泛型参数的多级 Java 泛型继承
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/11560980/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Multilevel Java generic inheritance using extends on generic parameters
提问by Engineer
I have
我有
public class First<T> {}
public class Second<T extends SomeConcreteClass> extends First<T> {}
public class Third<T> extends Second<T> {} //Compile-time error
I get the compile-time error
我收到编译时错误
Type argument T is not with bounds of type-variable T.
When I contruct a Third
, I want to be able to give the generic parameter as SomeConcreteClass
(or derived class thereof), and for a run-time error to be thrown if I've offered up a type that is not part of SomeConcreteClass
's inheritance hierarchy.
当我构造 a 时Third
,我希望能够将泛型参数作为SomeConcreteClass
(或其派生类)提供,并且如果我提供的类型不属于SomeConcreteClass
的继承层次结构,则会抛出运行时错误.
I would think that the specification in Second
's declaration would simply propagate downward, i.e. it should be implicit in the declaration (and any instantiations) of Third
.
我认为Second
的声明中的规范会简单地向下传播,即它应该隐含在 的声明(和任何实例化)中Third
。
What's with the error?
错误是怎么回事?
回答by Louis Wasserman
All you need is
所有你需要的是
public class Third<T extends SomeConcreteClass> extends Second<T>
You just need to respecify the bound. It doesn't propagate like you think it does.
您只需要重新指定界限。它不会像你想象的那样传播。
(I'm not positive of the reason for this, but I have some guesses -- what if it was Third<T> extends Second<Foo<T>>
? The appropriate bound on T
isn't obvious, if there even is one. So instead, it just doesn't propagate automatically; you have to specify it.)
(我不肯定这个原因,但我有一些猜测——如果是这样Third<T> extends Second<Foo<T>>
呢?适当的界限T
并不明显,如果有的话。所以相反,它只是不会自动传播;你必须指定它。)
回答by maasg
You have a downward propagation of the boundary restriction.
您有边界限制的向下传播。
If you'd put your code above in generic terms, you will clearly see the restricted declaration. Also, any further inheritance would also need to preserve or further narrow down that restriction. eg :
如果您将代码放在通用术语中,您将清楚地看到受限声明。此外,任何进一步的继承也需要保留或进一步缩小该限制。例如:
public class First<T> {}
public class Second<U, T1 extends U> extends First<T1> {}
public class Third<V, T2 extends V> extends Second<V,T2> {}
Note that it is now clear that you cannot have
请注意,现在很明显,您不能拥有
public class Third<T> extends Second<T> {}
As you are missing the required T2
type information for Second<V,T2>
.
When you use a concrete class, this restriction becomes implicit.
当你缺少所需T2
的类型信息Second<V,T2>
。当你使用一个具体的类时,这个限制就变得隐含了。
回答by codeslapper
In our case you can probably replace this:
在我们的情况下,您可能可以替换它:
public class Third<T> extends Second<T> {}
with this:
有了这个:
public class Third extends Second<SomeConcreteClass> {}
To use the T within the constructor and otherwise within the code such as a member field of type T, then you can do like this:
要在构造函数中使用 T 或者在代码中使用 T 类型的成员字段,那么您可以这样做:
VB2 extends VB1<Frag2>
...
public VB2(Frag2 frag){...
VB1<T extends Frag1> extends CommonVB<T>
...
public V1(T frag){... /// notice the T
CommonV<T extends CommonFragBase> extends BaseVB<T>
...
public CommonVB(T controller) {...
BaseVB<T extends CommonFragBase>
That works. The important thing is the generic on the concrete classes had to specify the actual concrete fragment class in order for the other code in the VB class to access its methods.
这样可行。重要的是,具体类上的泛型必须指定实际的具体片段类,以便 VB 类中的其他代码访问其方法。
回答by Rob Wagner
public class Third<T> extends Second<T> {}
public class Third<T> extends Second<T> {}
This is a bound mismatch. You can't extend Second with a generic T when you have just specified that second is of type T than extends SomeConcreteClass. When you extend Second, you need to do so with something that is within the scope of SomeConcreteClass.
这是一个绑定不匹配。当您刚刚指定 second 的类型为 T 而不是 extends SomeConcreteClass 时,您不能使用泛型 T 扩展 Second。当您扩展 Second 时,您需要使用 SomeConcreteClass 范围内的内容来扩展。
public class Third<T> extends Second<ClassThatExtendsSomeConcreteClass> {}
public class Third<T> extends Second<ClassThatExtendsSomeConcreteClass> {}
or just
要不就
public class Third<T> extends Second<SomeConcreteClass> {}
public class Third<T> extends Second<SomeConcreteClass> {}