2013-05-20 45 views
1

Java泛型我有相關的問題與ArrayList的

我有一個名爲Container像下面父母類Java泛型:容器可以包含其他容器和Services。 Services類擴展Container,但只能包含也擴展Container的ServiceMembers

即使在Services類中,我重寫父類的getElements()方法並返回也是Container類的子類的元素的ArrayList,但下面的代碼不起作用。

任何想法,我怎麼能得到這個工作,或者我只是用它錯誤的方式?

public class Container 
{ 
    protected ArrayList<Container> elements = new ArrayList<Container>(); 

    public ArrayList<Container> getElements() 
    { 
    } 
} 

public class Service extends Container 
{ 
    public ArrayList<ServiceMember> getElements() 
    { 
    } 
} 

回答

1

我認爲你只需要修改Container類是這樣的:

public class Container<T extends Container> { 
    protected List<T> elements = new ArrayList<T>(); 

    public List<T> getElements() { 
     return elements; 
    } 
} 

這將讓你與所有Container類的子類(或自己)參數化它。

Service類是這樣的:

public class Service extends Container<Service> { 

} 

在最後,你可以將這些類別實例的對象是這樣的:

Service s = new Service(); 
ArrayList<Service> elements = s.getElements(); 

Container<Container> c = new Container<Container>(); 
ArrayList<Container> els = c.getElements(); 

//adding an element to each of the lists: 
c.getElements().add(new Container<Container>()); 
System.out.println(c.getElements().size()); 

s.getElements().add(new Service()); 
System.out.println(s.getElements().size()); 

無論如何,我會建議你仔細考慮在設計上,因爲混合原始類與泛型是不安全和混亂的。

+0

請注意'Container'是'T extends Container'中的一個原始類型。 –

+0

嗨,謝謝你的迴應,同時我嘗試建議的解決方案..想知道你是否看到我的對象排列的方式基金缺陷..可以ü建議..謝謝 – Chandu

+0

也如何添加到元素列表?我試過你的建議,我能夠返回列表的類型,但我看到問題添加元素 – Chandu

1

即使在服務類我覆蓋了父母類的的getElements()方法,並返回這也是Container類的子類的元素的ArrayList下面的代碼不工作。

這是不正確的。由於類型擦除ArrayList<ServiceMember>不考慮重寫getElements()方法所需的協變式返回。

覆蓋如下。你不會失去多態性,它仍然會發生,因爲它取決於Object的類型(動態;在運行時),而不是它的引用類型(靜態;在編譯時)。

public class Service extends Container 
{ 
    public ArrayList<Container> getElements() 
    { 
    // declare superclass Container 
    ArrayList<Container> elements = new ArrayList<Container>(); 

    // but add subclass ServiceMember 
    elements.add(new ServiceMember()); 

    return elements; 
    } 
} 
+0

感謝您的答覆。我確實檢查了堆棧上的其他解釋並理解了這個問題。但我嘗試了一些解決方案以及其他帖子,但是我對Generic不是很熟悉,所以繼續問問題,看看有人能夠以正確的方式幫助我找到我正在做的事情的解決方案。有更好的方法來做到這一點 protected ArrayList <? extends Container> elements = new ArrayList (); – Chandu

-1

您需要Container,以表示對事物的類型包含:

public class Container<T extends Container<T>> { 
    private List<T> elements = new ArrayList<T>(); 

    public List<T> getElements() { 
     return elements; 
    } 
} 

public class Service extends Container<Service> { 
} 

注:

  • 類型T extends Container<T>似乎擴展其本身,但是這是你如何指定它這樣,你避免生的容器類型
  • 名單是私人:子類應該通過吸氣
  • 抽象類型List代替具體實施ArrayList良好做法簡單地訪問它,本着
+1

你能告訴我們你將如何實例化Container類嗎? –