2015-10-18 88 views
1

我有一個超類(動物)和兩個子類(青蛙和獅子)。在我下面的私人方法中,我創建了三個獅子和一個青蛙。我在第一個循環中顯示動物的所有四個重量,並在第二個循環中顯示所有獅子的名字。我得到正確的輸出,但是我的老師告訴我「在主方法中不需要創建兩個ArrayLists」。我猜他建議我使用我的第一個ArrayList來訪問我的Lion子類的getName()方法。通過超類對象的ArrayList訪問子類方法?

這是我做到了,這是工作:

import java.util.ArrayList; 

    public class AnimalTest { 

     public static void main(String[] args){ 
      ArrayList<Animal> animalList = createList(); 

      for(int i = 0; i < animalList.size(); i++){ 
       System.out.println(animalList.get(i).getWeight() + " lbs"); 
      } 

      ArrayList<Lion> lionList = createList(); 
      for(int j = 0; j < 3; j++){ 
       System.out.println(lionList.get(j).getName()); 
      } 

     } 

     private static ArrayList createList(){ 
      ArrayList<Animal> list = new ArrayList<Animal>(); 

      list.add(new Lion("Leo I", 530.00)); 
      list.add(new Lion("Leo II", 560.00)); 
      list.add(new Lion("Leo III", 590.00)); 
      list.add(new Frog("Freddie", 7.00)); 

      return list; 
     } 

    } 

難道他要我從我的獅類通過相同的ArrayList列表訪問我的getName()函數?我想我可以做一些鑄造做到這一點,就像這樣:

//ArrayList<Lion> lionList = createList(); 
for(int j = 0; j < 3; j++){ 
    System.out.println(animalList.(Lion)get(j).getName()); 
} 

但是,這並不工作..我不明白,我也應該去我的獅子子類的getName()方法,而不創建另一個的ArrayList ..

這裏是我班的其餘部分:

public class Animal { 
    private String genus; 
    private String species; 
    private double weight; 
    private boolean tail; 

    public Animal(){} 

    public Animal(String genus, String species){ 
     this.genus = genus; 
     this.species = species; 
    } 

    public String getGenus(){ 
     return genus; 
    } 

    public String getSpecies(){ 
     return species; 
    } 

    public double getWeight(){ 
     return weight; 
    } 

    public void setWeight(double weight){ 
     this.weight = weight; 
    } 

    public boolean hasTail(){ 
     return tail; 
    } 

    public void setTail(boolean tail){ 
     this.tail = tail; 
    } 

} 


public class Lion extends Animal { 
    private String name; 

    public Lion(){} 

    public Lion(String name, double weight){ 
     super("Panthera", "Leo"); 
     this.name = name; 
     setWeight(weight); 
     setTail(true); 
    } 

    public String getName(){ 
     return name; 
    } 
} 


public class Frog extends Animal { 
    private String name; 

    public Frog(){} 

    public Frog(String name, double weight){ 
     super("Lithobates", "Catesbeianus"); 
     this.name = name; 
     setWeight(weight); 
     setTail(false); 
    } 

    public String getName(){ 
     return name; 
    } 
} 
+0

做青蛙也有名稱(如「弗雷迪青蛙」) ?也許也是'getName()'方法?你的老師可能會建議你將'getName()'方法移到'Animal'類。 –

+0

是的青蛙也有一個getName()方法。該指令明確表示,在動物類中沒有關於動物名稱的任何內容,但是.. – JakeFromStateFarm

回答

1

父類無法訪問子類的字段或方法,因爲它不知道它實現了什麼。

考慮到這一點,合乎邏輯的做法是將您需要訪問的內容放在Animal類中。這意味着您要將name字段拉到父類Animal類中,而不是在那裏訪問它。

然後,你只需要一個ArrayList

ArrayList<Animal> animalList = createList(); 
for(Animal animal : animalList) { 
    System.out.println(animal.getWeight()); 
    System.out.println(animal.getName()); 
} 

此外,二非常重要更改您的createList方法需要發生:

  • 不返回原ArrayList。永遠。您需要正確輸入。

    public ArrayList<Animal> createList() { } 
    
  • 你不應該關心它作爲一個ArrayListList。相反,編程到List的界面是可取的(但不是必需的)。

    public List<Animal> createList() { } 
    

    獎勵積分,你可以阻止列表中的突變或者通過使其不變或使用PECS:

    public List<? extends Animal> createList() { } 
    
+0

@JakeFromStateFarm,所以,這個任務沒有說明你不能在Animal類中引用任何名字?引用你的評論:「......這些指令明確表示在Animal類中沒有關於動物名稱的任何內容,但是..」 – nihilon

+0

@nihilon正確,該作業只提到在特定動物的子類中添加該名稱。雖然我看不到他希望我怎麼做,但我已經嘗試過鑄造和一切。老實說,我認爲他沒有意識到他自己的指示說了什麼,哈哈。我認爲Makoto是對的,父類並不真正瞭解子類的字段或方法。週一我要親自去問我的導師。他在線給我發了這條消息,內容非常模糊。 – JakeFromStateFarm

+1

除非他希望你使用一個接口,那就是。但是那會有點愚蠢,因爲你已經*有一個共同的對象來引用。 – Makoto

0

你有正確的想法,你剛剛得到了劇組錯誤的語法。嘗試:

((Lion)animalList.get(j)).getName() 

儘管如果兩個青蛙和獅子可以有名字,那就更有意義,只是把getName()Animal類。

+1

這似乎是正確的,但它也不能正常工作..它說它無法在Animal類中找到getName()。它應該在獅子類而不是在這個鑄造動物類看,雖然,對嗎? – JakeFromStateFarm

1

您的createList函數返回一個raw-type,不要這樣做。另外,我建議你編程到界面。但你的第二個例子lionList似乎需要一個createLionList方法。類似的,

private static List<Lion> createLionList() { 
    List<Lion> list = new ArrayList<>(); 
    list.add(new Lion("Leo I", 530.00)); 
    list.add(new Lion("Leo II", 560.00)); 
    list.add(new Lion("Leo III", 590.00)); 
    return list; 
} 

然後我們可以修改第一個createList來添加它。喜歡的東西,

private static List<Animal> createList() { 
    List<Animal> list = new ArrayList<>(); 
    list.addAll(createLionList()); 
    list.add(new Frog("Freddie", 7.00)); 
    return list; 
} 

在你main方法,我寧願for-each loop。和formatted output。類似的,

List<Animal> animalList = createList(); 
for (Animal a : animalList) { 
    System.out.printf("Weight: %d lbs, Name: %s", a.getWeight(), 
      a.getName()); 
} 
+0

你的意思是我的方法簽名應該是ArrayList 返回類型而不是僅僅ArrayList?使用「List」而不是「ArrayList」是一回事嗎?另外,感謝您使用foreach循環的想法,這是有道理的,因爲我只是打印所有的動物而不是幾個選擇。 – JakeFromStateFarm

+1

@JakeFromStateFarm實質上就是他的意思。但是使用'List'作爲返回類型而不是'ArrayList'意味着你可以在稍後修改'ArrayList'到'LinkedList'或者'List'的其他一些實現,並且對代碼的其餘部分進行最小的修改是必要的。這不直接相關,而是一個免費的提示。 – nihilon

+0

噢,好的。我想我們還沒有涉及到「列表」,只是ArrayList .. – JakeFromStateFarm