gpt4 book ai didi

java - 调用通用接口(interface)方法不起作用

转载 作者:行者123 更新时间:2023-11-30 08:36:32 25 4
gpt4 key购买 nike

我得到了一个通用接口(interface),其中一个方法接受通用类型的参数:

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

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

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 的代码完成时,它告诉我,draw 接受一个类型为“null”的参数,因此出于某种原因,它无法弄清楚参数应该是哪种类型。 ..

最佳答案

问题是 ? extends GuiComponent 表示“GuiComponent 的一个特定子类型,但未知是哪个”。

编译器不知道 thisComponentRenderer 的正确 GuiComponent 子类型。渲染器可能只能与其他一些特定的子类一起工作。

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

例子:

class Gui {}

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

// T is the self-type. Subclasses will set it to their own type. In this way this class
// can refer to the type of its subclasses.
abstract class GuiComponent<T extends GuiComponent<T>> extends Gui {
private ComponentRenderer<T> componentRenderer;

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

public void setComponentRenderer(ComponentRenderer<T> r) {}

// This method is needed for the superclass to be able to use 'this'
// with a subclass type. Sub-classes must override it to return 'this'
public abstract T thisSub();

//and a setter and getter for the ComponentRenderer
}

// Here the self-type parameter is set
class GuiButton extends GuiComponent<GuiButton> {
public GuiButton(/* ... */) {
//...
this.setComponentRenderer(new FlatButtonRenderer());
}

class FlatButtonRenderer implements ComponentRenderer<GuiButton> {
@Override
public void draw(final GuiButton component) {
//...
}
}

@Override
public GuiButton thisSub() {
return this;
}
}

这最初(我认为)称为 curiously recurring template pattern . This answer更多解释。

关于java - 调用通用接口(interface)方法不起作用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37681306/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com