使用带有通配符的泛型类型作为自己的类型

时间:2014-01-24 21:22:13

标签: java android generics

这是我在Stackoverflow上的第一个问题,所以如果我做错了,请告诉我,以便下次我可以改进它。

由于我已经用Java完成了一些编程,甚至只有一些简单的东西已经有一段时间了,我仍然在学习很多关于很多功能的东西,并发现阅读本网站上的讨论很有帮助。

我认为我理解了Generics的工作方式,直到遇到以下问题。我知道它不是最好的设计,或者有其他方法可以用另一种方式来解决它,但是我们必须这样说。必须这样做。
(它是应用程序中的低层,所以我喜欢Generics与顶层的层建立连接。)

场合
基类IdentifieableGroupable扩展,该类可以通过ItemMutationLocation等进行扩展。

由于团体必须由这些东西组成,我补充说:

class Group<T extends Groupable> extends Groupable
{ 

    public Group(Id id)
    {
        super(id);
        content = new HashMap<T, Integer>();
    }

    private final HashMap<T, Integer> content;
            // Additional methods for adding, removing etc.
}

我在这里添加了Generic以限制能够将组限制为项目,突变等。组也必须是可分组的。

由于我希望能够知道我参与哪些群组,因此我设计了Groupable,如下所示:

    class Groupable extends Identifieable
    {

        public Groupable(Id id)
        {
            super(id);
            partOf = new ArrayList<Group<? extends Groupable>>();
        }

        private ArrayList<Group<? extends Groupable>> partOf;

        private final ArrayList<Group<? extends Groupable>> containingGroups()
        {
              return partOf;
        }
    }

问题
'partOf'的泛型类型让我感到痛苦。我需要返回一个扩展Groupable类型的组列表(当然),并间接取代该对象是其实例的类。当然,变异不能成为项目列表的一部分。

我考虑在Groupable中使用类型参数,但这对我来说似乎不正确。 这样你实例化一个Item,它把它的类作为它的父类的类型,这是可能但不好的。这样就可以返回和存储自己类型的组,但不能存储超类型的组。

最后
我不知道这是否清楚,我真的不知道如何通过保留所有元素来简化问题。

如果存在一个出色的解决问题的设计,请记住,所有这些类都应该以“通用”;)的方式进行扩展和使用,非常感谢。

我已经阅读过关于使用原始类型的内容,但这似乎并不正确,尽管假设不会发生错误的转换已经是安全的。如果有人能够通过通配符解释这个Generic-nesting以及解决这个特定问题的正确方法,那么非常感谢。

我对正确的方式更感兴趣,或者理论解释比解决方法更新,还没有错误,因为我不知道如何实现它。

1 个答案:

答案 0 :(得分:1)

您不能规定Groupable类包含一组Groups。它的主要原因是Group类扩展了Groupable,因此在编译Groupable类时它不是(不能)知道的。

这里还有一个问题是它对我来说没有意义。例如,如果Groupable类被Item类扩展了。它是否有意义包含一组群 - 考虑到它基本上是它的兄弟,但唯一可以连接它们的是一个共同的父母。

我建议用这种方式修改代码:

class Groupable extends Identifiable
{
    private ArrayList<? extends Groupable> partOf;

    public Groupable(String id)
    {
        partOf = new ArrayList<Groupable>();
    }


    private final ArrayList<? extends Groupable> containingGroups()
    {
          return partOf;
    }
}