2014-11-24 57 views
2

泛型和摘要令人難以理解,因此請耐心等待,同時儘量以簡單的方式解釋問題。管理Java中泛型列表中的抽象子類

我有以下類別:

public class Community<T extends Person> { 
    List<T> people; 

    public void add(T person) { 
     people.add(person); 
    } 

    public List<T> getPeople() { 
     return people; 
    } 
} 

public abstract class Person {} 

public class Aussie extends Person {} 

這裏是實例澳大利亞人的社區代碼:

Aussie aus1 = new Aussie(); 
Aussie aus2 = new Aussie(); 

Community<Aussie> aussieCommunity = new Community<>(); 
aussieCommunity.add(aus1); 
aussieCommunity.add(aus2); 

現在讓我們更進一步,說我有多個社區,我希望系統地存儲在列表內如下:

List<Community<?>> communities; 

我希望你還是跟我因爲這裏是我的問題:

我需要編寫,將採取社區的列表,並顯示每個人的詳細信息的代碼 - 假設每個人的細節將有所不同在自己的類訪問。例如:澳大利亞人可能會說「嗨」,嗨,美國人會說「你好」。

for (Community<?> community : communities) { 
    // I don't know what the type of community this is so, I use wildcard: 
    List<? extends Person> people = community.getPeople(); 
    for (Type person : people) { // How do I specify the type of person eg Aussie/American etc here? 
     // Do something 
    } 
} 

任何關於如何指定第二個循環中的人員類型的建議?

+1

爲什麼你不使用的人的抽象方法? – Mailkov 2014-11-24 08:27:13

+1

同意Mailkov。在Person中放置一個抽象方法並在所有子類中覆蓋它。那麼你不需要知道它在循環中是什麼樣的人。繼承會爲你解決問題。 – AppX 2014-11-24 08:28:53

+0

'people.add(person);'在'Community#getPeople'會給你一個錯誤。 – 2014-11-24 08:29:46

回答

0

好的。這裏是它如何做一個小例子:

public abstract class Person { 
    public final String say(String sentance) { 
     StringTokenizer tokenizer = new StringTokenizer(sentance); 
     StringBuilder sb = new StringBuilder(); 
     while (tokenizer.hasMoreTokens()) { 
      String word = tokenizer.nextToken(); 
      String slang = getSlang(word); 
      sb.append(slang != null ? slang : word); 
      sb.append(tokenizer.hasMoreTokens() ? " " : ""); 
     } 
     return sb.toString(); 
    } 

    private String getSlang(String word) { 
     return getSlangMap().get(word); 
    } 

    protected abstract Map<String, String> getSlangMap(); 
} 


public class Aussi extends Person { 
    @Override 
    protected Map<String, String> getSlangMap() { 
     Map<String, String> slangMap = new HashMap<>(); 
     slangMap.put("hi", "Oi"); 
     slangMap.put("there", "theeer"); 
     return slangMap; 
    } 
} 

public class Swede extends Person { 
    @Override 
    protected Map<String, String> getSlangMap() { 
     Map<String, String> slangMap = new HashMap<>(); 
     slangMap.put("hi", "hejsan"); 
     slangMap.put("there", "där"); 
     return slangMap; 
    } 
} 

public class CommunityTest { 
    @Test 
    public void testSayHiThere() throws Exception { 
     Aussi au1 = new Aussi(); 
     Aussi au2 = new Aussi(); 
     Community<Aussi> aussiCommunity = new Community<>(); 
     aussiCommunity.add(au1); 
     aussiCommunity.add(au2); 

     Swede sw1 = new Swede(); 
     Swede sw2 = new Swede(); 
     Community<Swede> swedeCommunity = new Community<>(); 
     swedeCommunity.add(sw1); 
     swedeCommunity.add(sw2); 

     List<Community<? extends Person>> communities = new ArrayList<>(); 
     communities.add(aussiCommunity); 
     communities.add(swedeCommunity); 

     for (Community<? extends Person> community : communities) { 
      for (Person person : community.getPeople()) { 
       System.out.println(person.say("hi there")); 
      } 
     } 
    } 
}