Java 泛型中的嵌套扩展
我有三门课:Java 泛型中的嵌套扩展,java,generics,Java,Generics,我有三门课: class ClassR {} class ClassA<T extends ClassR>{} class ClassB<E extends ClassA<T extends ClassR>> extends ClassA<T> { void foo(T param) { } void bar(E param) { } } ClassR{} 类ClassA{} 类B扩展了类A{ 无效foo
class ClassR {}
class ClassA<T extends ClassR>{}
class ClassB<E extends ClassA<T extends ClassR>> extends ClassA<T> {
void foo(T param) {
}
void bar(E param) {
}
}
ClassR{}
类ClassA{}
类B扩展了类A{
无效foo(T参数){
}
空栏(E参数){
}
}
第三个类不会编译,除非我将其更改为
class ClassB<E extends ClassA<T>, T extends ClassR> extends ClassA<T> {
void foo(T bar) {
}
void bar(E param) {
}
}
ClassB扩展了ClassA{
无效foo(T bar){
}
空栏(E参数){
}
}
有没有办法在创建ClassB时只保留我需要传递的E参数,并且推断T?例如,可以方便地使用:
new ClassB<ClassA<ClassR>>()
newclassb()
而不是:
new ClassB<ClassA<ClassR>, ClassR>()
newclassb()
不确定这是否是您想要的答案,但最简单的版本肯定是:
class ClassR {
}
class ClassA<T extends ClassR> {
}
class ClassB<T extends ClassR> extends ClassA<T> {
void foo(T bar) {
}
}
public void test() {
ClassB<ClassR> classB = new ClassB<>();
}
ClassR类{
}
甲级{
}
类B扩展了类A{
无效foo(T bar){
}
}
公开无效测试(){
ClassB ClassB=新的ClassB();
}
这种更简单的方法可能适合您:
class ClassR {}
class ClassA<T extends ClassR>{}
class ClassB<T extends ClassR> extends ClassA<T> {
void foo(T bar) {
}
void bar(ClassA<T> param) {
}
}
当type
E
扩展ClassA
时,您可以安全地在其声明中省略ClassA
类型参数。在
ClassB
的第二个参数中强制执行适当的ClassA
类型参数请参见下面的代码以获取说明:
class ClassB<E extends ClassA, T extends ClassR> extends ClassA<T> {
private ClassA ob;
public ClassB(E e, T t) {
super(t);
ob = e;
}
}
ClassB扩展了ClassA{
私人甲级ob;
公共B类(E、T、T){
超级(t);
ob=e;
}
}
使用示例:
class ClassR {
public ClassR() {};
}
class ClassS extends ClassR {
private int x;
public ClassS(int x) {
super();
this.x = x;
}
}
public static void test() {
ClassS data1 = new ClassS(1);
ClassB <ClassB, ClassS> first = new ClassB<>(null, data1);
ClassS data2 = new ClassS(2);
ClassB <ClassB, ClassS> second = new ClassB<>(first, data2);
}
ClassR{
公共类r(){};
}
类扩展了ClassR{
私人INTX;
公共类(int x){
超级();
这个.x=x;
}
}
公共静态无效测试(){
ClassS data1=新类(1);
ClassB first=新的ClassB(null,数据1);
ClassS data2=新类(2);
ClassB second=新的ClassB(第一个,数据2);
}
旁注:实现Runnable比扩展Thread要好。改为ClassR,因为它与EAre没有区别请使用post方法你可以用E做任何事情吗?黑暗中拍摄:ClassB扩展ClassA
有效吗?我的错,我在ClassB中同时使用E和T,有办法仍然使用E吗?(更新了问题)使用此解决方案,您可以在继承ClassA的同时将ClassA作为rawtype。每当您需要“E extends ClassA”中ClassA的泛型类型信息时,您就会迷失方向。如上所述,我认为存在一些设计缺陷,使我们无法提供良好的实现,因为显示的代码闻起来像是隐含的需求。我认为这是一个很好的答案。从显示的代码判断,“E”永远不会从ClassB中的方法返回。然而,在ClassB中(例如在方法“bar”中),您(编译器)只知道它是可以看作ClassA的东西。因此,您只能以类型安全的方式从ClassA和T调用mthods。因此,不需要类型参数“E”。然而,如果有代码引用调用“E”方法的ClassB实例,情况就完全不同了。
class ClassR {
public ClassR() {};
}
class ClassS extends ClassR {
private int x;
public ClassS(int x) {
super();
this.x = x;
}
}
public static void test() {
ClassS data1 = new ClassS(1);
ClassB <ClassB, ClassS> first = new ClassB<>(null, data1);
ClassS data2 = new ClassS(2);
ClassB <ClassB, ClassS> second = new ClassB<>(first, data2);
}