调用通用接口方法不起作用

时间:2016-06-07 13:49:37

标签: java generics interface

我有一个通用接口,其中一个方法接受泛型类型的参数:

public interface ComponentRenderer<T extends GuiComponent> {
    public void draw(T component);
}

此外,我有一个抽象类,使用有界通配符声明此接口类型的变量:

public abstract class GuiComponent extends Gui {
    private ComponentRenderer<? extends GuiComponent> componentRenderer;

    public void draw() {
        this.componentRenderer.draw(this);
    }

    //and a setter and getter for the ComponentRenderer
}

一个子类,它为componentRenderer设置了一个实现:

public class GuiButton extends GuiComponent {
    public GuiButton(/* ... */) {
        //...
        this.setComponentRenderer(new FlatButtonRenderer());
    }

其中FlatButtonRenderer实现为:

public class FlatButtonRenderer implements ComponentRenderer<GuiButton> {

    @Override
    public void draw(final GuiButton component) {
        //...
    }
}

我无法看到出错的地方,但GuiComponent中的调用componentRenderer.draw(this)无法解决以下错误:

enter image description here

据我所知,它告诉我,我不能使用GuiComponent,因为它不是来自GuiComponent,没有任何意义。我还尝试? super GuiComponent,它会接受draw()来电,但之后不接受FlatButtonRenderer的实施

我不明白这种语法错误,有没有人有想法,我需要如何更改代码?

编辑: 当我在调用draw()时使用我的IDE代码完成时,它告诉我,那个绘制接受一个类型&#34; null&#34;的参数,所以由于某种原因,它无法计算out,这个论点应该是......

2 个答案:

答案 0 :(得分:2)

问题在于conn.getLocalCache().setEnable(false);表示“? extends GuiComponent的一个特定子类型,但未知哪个”。

编译器不知道GuiComponent属于this的{​​{1}}子类型GuiComponent。可能是渲染器只能与其他特定子类一起使用。

您必须使用某种自我类型模式以类型安全的方式执行此操作。这样你就可以将渲染器的类型变量与ComponentRenderer子类的类型“连接”起来。

示例:

GuiComponent

这最初(我认为)称为curiously recurring template patternThis answer解释得更多。

答案 1 :(得分:0)

在GuiComponent中,将componentRenderer的声明更改为:

ComponentRenderer<GuiComponent> componentRenderer;