【问题标题】:List Polymorphism列表多态性
【发布时间】:2014-01-07 20:20:21
【问题描述】:

我有这些课程:

class Parent {
    public Parent() {
    }
}

class ChildA extends Parent {
    public ChildA() {
        super();
    }
}

class ChildB extends Parent {
    public ChildB() {
        super();
    }
}

public ListClas(List(Parent) list)   {
    this.list=list;
    }
}

我想运行ListClas构造函数如下。

List<ChildA> list_childA = new ArrayList<ChildA>();

List<ChildB> list_childB = new ArrayList<ChildB>();

ListClas listClasA = new ListClas(list_childA);

ListClas listClasB = new ListClas(list_childB);

但是编译器会抛出一个错误。如何使用多态性正确执行此操作?

【问题讨论】:

  • 你认为你在哪里使用多态性?泛型和多态不是一回事。阅读this
  • 错误是什么? ListClas 看起来怎么样?
  • public ListClas(List(Parent) list) { this.list=list; } }
  • public ListClas(List(Parent) list) 不是有效的 Java。你的意思是public ListClas(List&lt;Parent&gt; list)

标签: java list polymorphism


【解决方案1】:

如果你想要一个接受包含超类的子类的 List 的函数,你应该使用语法。

public ListClas(List<? extends Parent> list){
    this.list=list;
}

它会同时接受它们。

ListClas listClasA = new ListClas(list_childA);

ListClas listClasB = new ListClas(list_childB);

【讨论】:

  • 这取决于this.list 是什么类型。如果它只是一个List,那么它会工作,但如果它是一个List&lt;Parent&gt;,那么它不会工作,因为你会将List&lt;ChildA&gt; 类型的实例分配给List&lt;Parent&gt; 类型的变量
【解决方案2】:

如果您在 ListClas 中更改为 List&lt;? extends Parent&gt; list(同时更改 ListClas.list 字段定义),那么它将编译并工作。

【讨论】:

  • 这取决于list 是什么类型。如果它只是一个List,那么它会工作,但如果它是一个List&lt;Parent&gt;,那么它不会工作,因为你会将List&lt;ChildA&gt; 类型的实例分配给List&lt;Parent&gt; 类型的变量
  • List&lt;Parent&gt; 可以分配List&lt;? extends Parent&gt;以及List&lt;ChildA&gt;List&lt;ChildB&gt;。你可以验证一下,或者我可能误解了你。
  • List&lt;? extends Parent&gt; list = new ArrayList&lt;ChildA&gt;(); 有效,但 List&lt;Parent&gt; list = new ArrayList&lt;ChildA&gt;(); 无效。 OP 没有显示整个 ListClas 类,因此不清楚 this.list 是什么类型。从OP中ListClas构造函数参数list的类型来看,我假设this.list的类型也是List&lt;Parent&gt;
  • 我认为ListClas.list 字段定义也必须更改。
【解决方案3】:

所有这些:List&lt;Parent&gt;List&lt;ChildA&gt;List&lt;ChildB&gt;都是不同的具体参数化类型。

您可以在此处阅读更多信息:https://stackoverflow.com/a/20940807/516167

【讨论】:

  • 我认为这里的问题更多是List&lt;ChildA&gt;被分配给List&lt;Parent&gt;
【解决方案4】:

我认为您希望您的 ListClas 看起来像这样:

class ListClas<T>
{
    private List<T> list;

    public ListClas(List<T> list)
    {
        this.list = list;
    }
}

然后创建它们:

ListClas<ChildA> listClasA = new ListClas<ChildA>(list_childA);
ListClas<ChildB> listClasB = new ListClas<ChildB>(list_childB);

T 是通用类型名称。它允许您将同一个类用于多种运行时类型。所以你可以做上面的而不是写这个:

class AListClas
{
    private List<ChildA> list;

    public AListClas(List<ChildA> list)
    {
        this.list = list;
    }
}

class BListClas
{
    private List<ChildB> list;

    public BListClas(List<ChildB> list)
    {
        this.list = list;
    }
}

如果您不需要那么大的灵活性,您可以这样编写您的 ListClas:

class ListClas
{
    private List<? extends Parent> list;

    public ListClas(List<? extends Parent> list)
    {
        this.list = list;
    }
}

并像这样使用它:

ListClas listClasA = new ListClas(list_childA);
ListClas listClasB = new ListClas(list_childB);

【讨论】:

  • 但是看不懂T,这个例子是什么?
  • 你使用的是什么JDK版本?
  • 我添加了第二个可能对您有用的实现。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-03-19
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多