2014-09-05 18 views
0

我剛剛閱讀了關於Java中的通配符的問題,我正在研究一個我有2個類的情況,即ParentClass和繼承自它的SubClass。 (ParentClass,SubClass繼承父類)關於Java中的通配符的簡單說明

現在我寫這些行。

List<? super ParentClass> list1 = new ArrayList<ParentClass>(); 
list1.add(new SubClass()); 

我不明白爲什麼編譯和運行。不應該第2行導致編譯錯誤,因爲我試圖將ParentClass的孩子添加到應該只保存父類父親的列表中?

謝謝!

+0

它是完全有效的按多態。 list1是父類的列表,它可以容納子對象。然而,在相反的情況下它是無效的情況。 – 2014-09-05 19:55:58

+0

謝謝大家,我現在明白了(: – 2014-09-05 20:03:11

+0

做了一些更多的研究並更新了我的答案.PECS規則值得理解。 – DolphinJava 2014-09-05 20:41:56

回答

0

根據Java多態性功能 可以將您的子類對象分配給父類的引用類型。 這裏是將子類分配給ParentClass類型的引用。

這就是爲什麼它的工作

嗨,

[這](What is PECS (Producer Extends Consumer Super)?)應該真正幫助你理解。有一條規則叫做PECS。生產者延伸和消費者超級。這條規則應該包含在通配符的Java教程中,因爲如果沒有這個,對Bounded通配符的理解對我來說似乎就不完整了。

這基本上意味着,如果你只想從列表中讀(寫不進的話),然後用

List<? extends ParentClass> 

它表明你會得到哪些是父類或父類的亞型的對象。此外,暗示列表處於只讀模式。

如果你想「把」到沒有讀取列表,然後通過聲明您的列表,

List<? Super ParentClass> 

您可以添加或者是父類或它的類型的類型。但沒有別的可以插嘴說。

而且,寫了下面的代碼,並

1 List<? super ChildClass > list1 = new ArrayList<ChildClass>(); 
2  list1.add(new GrandChildAbstract()); 
3  list1.add(new ChildClass()); 
4  list1.add(new Abstractclass()); 
5  
6  ChildClass ch= list1.get(0); 
7  Abstractclass ch = list1.get(0); 
8  
9  List<? extends ChildClass> list2 = new ArrayList<ChildClass>(); 
10  list2.add(new GrandChildAbstract()); 
11  list2.add(new ChildClass()); 
12  list2.add(new Abstractclass()); 

,且Eclipse編譯的時候出錯了線#4,6,7日和10,11,12 這清楚地表明必須在只讀和只寫上下文的背景下理解超級綁定通配符。

+0

謝謝,沒想到那個(: – 2014-09-05 19:55:34

4

List<? super ParentClass>類型的意思是「至多是父類的某些未知類型的列表」。如果你有接受了這種類型的參數的方法,你可以通過它List<ParentClass>類型,List<GrandparentClass>的東西,...,List<Object> ...

void x(List<? super ParentClass> list) { 
    list.add(new SubClass()); 
} 

這些類型的任何列表會承認一個電話add使用類型​​的參數。因此,無論方法x中的list的類型如何,調用add都會保持類型安全。

1

繼承關係表示爲「是」:您的​​是ParentClass,而ParentClass是其超類等的實例。所以編碼可以隨時設置​​任何地方它的祖先的ParentClass或任何時候:

SubClass subClass = new SubClass(); 
ParentClass aParent = subClass; 
0

嗯,看來你是混淆的條款。

當你說

List<? super ParentClass> list1; 

你說,列表1將接受所有的列表,該列表的類型是父類以上。

此代碼不起作用,因爲SubClass不是ParentClass的超類。

List<? super ParentClass> list1 = new ArrayList<SubClass>(); 

當你寫

List<? super ParentClass> list1 = new ArrayList<ParentClass>(); 

是等於

List<ParentClass> list1 = new ArrayList<ParentClass>(); 

,一旦子類是父類的亞型:

list1.add(new SubClass()); 

運行正常。

ps:抱歉我的英語不好。