为接受T的泛型方法提供具体的类实例,其中T扩展具体类

时间:2014-07-17 11:21:44

标签: java generics

我有一个类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将无法编译。

2 个答案:

答案 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,则会有效。

相关问题