[英]Nested generic collections
不用担心细节,我的代码代表了一个图书馆,每本书由一组页面和一组单词组成。
我创建了自己的Set实现:
class PageSet<E> extends HashSet<E>(){
public boolean set(int index, E e){....}
....
}
和
class WordSet<E> extends HashSet<E>(){
public boolean set(int index, E e){....}
....
}
当我尝试在主班级创建一本书时,我陷入了困境:
Set<Set<Word>> dictionary = new PageSet<WordSet<Word>>();
导致类型转换不匹配。 但是它会很高兴地接受
Set<Set<Word>> dictionary = new PageSet<Set<Word>>();
使用这种通用设置时,有人可以说明我做错了什么吗?
基本上, PageSet<WordSet<Word>>
不是Set<Set<Word>>
,因为X<Subclass>
不是X<Superclass>
。
如果你说过
Set<WordSet<Word>> dictionary = new PageSet<WordSet<Word>>();
那么那也行得通。
要么
Set<Set<Word>> dictionary = new PageSet<Set<Word>>();
要么
Set<WordSet<Word>> dictionary = new PageSet<WordSet<Word>>();
由于尽管WordSet
是Set
的子类,所以Set<WordSet>
不是Set<Set>
的子类。
换句话说,泛型不是协变的 ,这与数组之类的东西不同。
无论如何,除非您试图创建新的集合类型,否则不应该扩展集合。 由于您不能限制子类中超类方法的可见性,因此人们可以编写
WordSet<Word> words = ...;
words.clear();
您可能不想赋予客户这种权力。 而是使用聚合而不是继承。
class Word {
private String text;
private PartOfSpeech part;
// Constructors, getters, setters, equals, hashCode are elided.
}
class Page {
private int pageNumber;
private Set<Word> contents = new HashSet<>();
public class Book {
private String title;
private List<Page> pages = new ArrayList<>();
}
一本书中的页面是线性排列的,这就是我使用列表的原因。 我不确定为什么要使用布景。 但是无论如何,通过将集合封装在类中,可以为客户端代码提供您希望它们使用的确切接口。 可见性是故意选择的; 这看起来像一堆相关的类,但是您可能想要更改它们。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.