gpt4 book ai didi

java - 无法理解泛型和继承

转载 作者:行者123 更新时间:2023-12-02 09:13:31 27 4
gpt4 key购买 nike

当谈到泛型和继承时,我有点纠结。总体思想是各种组件以及包含其他组件的组或容器组件的构建器模式。有些组件组需要特定组件,有些可以是任何组件。这就是问题所在。我认为最好用代码解释:

public abstract class AbstractGroupComponentBuilder <T extends ComponentGroup<R>, R extends AbstractDashboardComponent> implements ComponentBuilder<ComponentGroup<R>> {
private List<ComponentBuilder<R>> children;
protected void child(ComponentBuilder<R> builder){
children.add(builder);
}
...
}

public class ComponentGroupBuilder extends AbstractGroupComponentBuilder<ComponentGroup<AbstractDashboardComponent>, AbstractDashboardComponent>{

public <T> TableBuilder<T> table(Class<T> clazz){
TableBuilder<T> builder = new TableBuilder<T>(clazz);
child(builder); // PROBLEM HERE: The method child(ComponentBuilder<AbstractDashboardComponent>) in the type AbstractGroupComponentBuilder<ComponentGroup<AbstractDashboardComponent>,AbstractDashboardComponent> is not applicable for the arguments (TableBuilder<T>)

}
...
}

public class TableBuilder<T> implements ComponentBuilder<Table> {
...
}

public class Table extends AbstractDashboardComponent{
...
}

public class ComponentGroup<T extends AbstractDashboardComponent> extends AbstractDashboardComponent {
...
}

public interface ComponentBuilder<T extends AbstractDashboardComponent> {
public T build();
}

所以编译器的错误是:"The method child(ComponentBuilder<AbstractDashboardComponent>) in the type AbstractGroupComponentBuilder<ComponentGroup<AbstractDashboardComponent>,AbstractDashboardComponent> is not applicable for the arguments (TableBuilder<T>)"为什么从 TableBuilder<T> extends ComponentBuilder<Table> 开始就不兼容?和“表扩展 AbstractDashboardComponent”。

最佳答案

在这里,您的构建器类型为TableBuilder<Table> 。这与 ComponentBuilder<AbstractDashboardComponent> 不兼容。问题不是ComponentBuilder ,这是 <> 里面的东西。与普通类型不同,侧面的东西 <>不变,这意味着类型必须完全匹配,不允许有子类型。

原因如下:我将使用非常简单且熟悉的类型来解释它:

List<Integer> ints = new ArrayList<Integer>();
List<Number> numbers = ints; // PROBLEM LINE
numbers.add(5.0);
ints.get(0); // uhoh - that's a double and not an int!

标记为 PROBLEM 的行?那不会编译。修复方法如下:

List<Integer> ints = new ArrayList<Integer>();
List<? extends Number> numbers = ints; // this is fine
numbers.add(5.0); // PROBLEM LINE
ints.get(0); // uhoh - that's a double and not an int!

在此示例中,错误位于第三行:您无法将任何内容添加到 List<? extends NothingYouTypeHereCanFixThat> (不相关的细节:除了文字 null )。

这就是为什么第 2 行现在没问题了。

你需要做同样的事情并抛出一些? extends直到编译为止。

<T> = 不变;只有精确的 T 才有效,但您可以按照您想要的方式使用 T。

<? extends T> = 协变; T 或 T 的任何子类型都可以,但只能调用 get 风格的方法。

<? super T> = 逆变; T 或 T 的任何 SUPERTYPE 都可以,但您只能调用 add 样式的方法(您可以调用 get,但只能获取 Object)。

逆变很少出现。它可以让你做:

List<? super Integer> list = ...;
list.add(5); // compiles fine.
Object o = list.get(0); // all you get is `Object` here.

如果您有List<Number> ,您可以将其分配给列表变量。

关于java - 无法理解泛型和继承,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59199777/

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