我有一个类ShapeDescriber
,如下所示:
public class ShapeDescriber<T extends Shape> {
public void describe(T shape) {
System.out.println("Its color is " + shape.getColor());
}
}
我使用T
,以便子类可以执行以下操作:
public class CircleDescriber<T extends Circle> extends ShapeDescriber<T> {
public void describe(T circle) {
super.describe(circle);
System.out.println("Its radius is " + circle.getRadius());
}
}
最终,我希望此Describer
类型层次结构与我的模型的类型层次结构相匹配。
我遇到的问题是,在CircleDescriber
内部,我无法将Circle
传递给我的describe()
方法!当我尝试这个时:
public class CircleDescriber ... {
...
public void printATest() {
Circle c = new Circle(Colors.GREEN, 10);
this.describe(c);
}
}
我的describe()
来电时出现编译错误,原因是:
The method describe(T) in the type CircleDescriber<T> is not applicable for the arguments (Circle)
等待。 什么?我觉得这个类知道 T
的每个实例都是Circle
的子类,不是吗?
修改:我在这里创建了一个Gist,以便轻松进行复制:https://gist.github.com/craigotis/135f88b1ce8beca07400
注意上面的Gist将无法编译。
答案 0 :(得分:3)
我认为这应该按原样运行,但取决于你如何实例化CircleDescriber
。这应该有效:
new CircleDescriber<Circle>().describe(circle);
这不能编译的原因是你在CircleDescriber
内有测试方法,并调用this
。由于编译器不知道this
的泛型参数,因此无法确定将Circle
传递给它会起作用(如果this
引用CircleDescriber
该怎么办?参数化为Circle
的子类?)在测试方法中使用this
更改new CircleDescriber<Circle>()
,然后进行编译。
但是,在这里你可以看到你实际上在类名和泛型参数中指定了两次Circle
。这不应该是必要的,至少只要Circle
是层次结构中的叶节点。相反,这样做:
(保持ShapeDescriber
原样)
public class CircleDescriber extends ShapeDescriber<Circle> {
@Override
public void describe(Circle circle) {
super.describe(circle);
System.out.println("Its radius is " + circle.getRadius());
}
}
答案 1 :(得分:1)
声明:
public class CircleDescriber<T extends Circle> extends ShapeDescriber<T>
意味着
CircleDescriber.describe()
获得一些扩展Circle
的课程。例如:
有一个班级:public class RedCircle extends Circle
,您可以声明:
CircleDescriber describer = CircleDescriber<RedCircle>
表示describer
只能获得RedCircle
(不 Circle
)。这就是不被允许的原因。
更改为:
public class CircleDescriber extends ShapeDescriber<Circle>
如果您只能使用Circle
,则会有效。