首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >在泛型和继承方面有困难。

在泛型和继承方面有困难。
EN

Stack Overflow用户
提问于 2019-12-05 16:48:44
回答 1查看 47关注 0票数 0

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

代码语言:javascript
复制
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>和'Table扩展了抽象AbstractDashboardComponent‘。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2019-12-05 16:58:35

在这里,您的生成器是TableBuilder<Table>类型的。这与ComponentBuilder<AbstractDashboardComponent>不兼容。程序不是ComponentBuilder,而是<>内部的东西。与普通类型不同,side <>中的内容是不变的,也就是说,这些类型必须完全匹配,不允许子类型。

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

代码语言:javascript
复制
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?那就不能编译了。解决办法是:

代码语言:javascript
复制
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> =不变量;只有精确的Ts才能计算出来,但是您可以以所有想要的方式使用T。

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

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

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

代码语言:javascript
复制
List<? super Integer> list = ...;
list.add(5); // compiles fine.
Object o = list.get(0); // all you get is `Object` here.

如果您有一个List<Number>,您可以将它赋值给list变量。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/59199777

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档