2011-11-11 37 views
0

只需在我的文章頂部進行快速編輯即可。 問題是如果我擴展一個類,並且兩個類具有相同的變量爲什麼擴展類獲取原始類的值。擴展類中的變量沒有得到正確的值

這已被回答,但會更樂意閱讀關於此的更多信息。 多態性不是我的強項,所以我不得不在幾個月後重新使用它。

所以我想編程一個遊戲,其中一個需求是某種類型的可以在循環中掃描的對象列表。麻煩從我測試ArrayList開始。我有3個課程被添加到我的數組列表中。實體,怪物擴展實體,字符擴展實體。注意怪物和人物都擴展實體類。 我決定我應該創建ArrayList並將新對象直接添加到每個元素中(單詞元素通常與數組一起使用,而不是ArrayList正確?),並使用一個日誌函數編程來記錄ArrayList中對象的值。 我做了一個循環,並運行它們從實體繼承的怪物和字符.getHP()方法,結果是實體的HP不是怪物或字符,除非我使用setHP(int i )方法也繼承了Entities。

因爲我的程序需要大部分的類,我們只需要大約99%,我決定做一個測試項目,基本上做一個更小的形式,因爲我不想複製粘貼20或更多.java文件在這裏。無論如何,這裏是我的測試課程和結果。

import java.util.ArrayList; 

    // class to test interactions between Extended classes 
    public class testHP { 
     ArrayList<Entities> ent = new ArrayList<Entities>(); 

     public static void main(String[] args) { 

      ///make reference varaible so i don't have to make test() and ent static. 
      testHP hp = new testHP(); 
      hp.test(); 
     } 
     void test(){ 
      /// the 3 classes to the arraylist. I could of made a reference variable but didn't. 
      this.ent.add(new Character()); 
      this.ent.add(new Monster()); 
      this.ent.add(new NPC()); 
      ///prints out whats in the array list so i know that i have the correct objects. 
      System.out.println(this.ent); 

      /// this prints out { ent(i) HP "is" i } to tell which class is being called and it's HP at this point. 
      for(int i=0; i<ent.size();i=i+1) {System.out.println(this.ent.get(i).getHP() +" is "+ this.ent.get(i));} 
      /// this adds i plus 10 then does the same as the last for loop. 
      for(int i=0; i<ent.size();i=i+1) { 
       this.ent.get(i).gainHP(i+10); 
       System.out.println(this.ent.get(i).getHP() +" is "+ this.ent.get(i));} 
     } 
    } 



abstract public class Entities { 
    private int HP = 1; 

    int getHP(){ 
     return HP; 
    } 
    void gainHP(int hp){ 
     HP = this.HP + hp; 
    } 
} 



///Character is to show what happens when i change the value and make it static. 
public class Character extends Entities { 
    private static int HP = 4; 
} 


///monster is to show a changed variable from the super which is entities. 
public class Monster extends Entities { 
    private int HP = 4; 

} 

/// NPC is a class that just to have variables from entities class that aren't edited or made static. 
public class NPC extends Entities { 

} 

這是我的結果與這些文件,因爲他們上面。我應該把惠普旁邊的號碼放在左邊,但你明白了。

[[email protected], [email protected], [email protected]] 
1 is [email protected] 
1 is [email protected] 
1 is [email protected] 
11 is [email protected] 
12 is [email protected] 
13 is [email protected] 

我原來的ArrayList的測試類看起來像這樣。

import java.util.ArrayList; 
public class AreaMap extends Map { 


    String CLASS = "Area Map";///log requires. 
    ArrayList<Entities> ent = new ArrayList<Entities>();  
    AreaMap(){ 
     Log.Logging(CLASS,"Testing arrayList"); 

     //random text added to the array. 
     ent.add(new Character()); 
     ent.add(new Monster()); 
     Log.Logging(CLASS, "ent 1 has " +ent+ " in it"); 
     for(int i=0; i < ent.size();i = i+1){ 
     Log.Logging(CLASS, "ArrayList " + this.ent.get(i).getHealth() +" i="+i); 
     } 
     for(int i=0; i < ent.size();i = i+1){ 
      this.ent.get(i).setHP(10+i); 
     Log.Logging(CLASS, "ArrayList " + this.ent.get(i).getHealth() +" i="+i); 
     } 
    } 
} 

這是我的結果。

[Area Map]##[Testing arrayList] 
[Area Map]##[ent 1 has [[email protected], [email protected]] in it] 
[Area Map]##[ArrayList 0 i=0] 
[Area Map]##[ArrayList 0 i=1] 
[Area Map]##[ArrayList 10 i=0] 
[Area Map]##[ArrayList 11 i=1] 

別注意,「日誌」是I類製成,並且方法是「靜態記錄(字符串原點,字符串操作){的System.out.println([原點] +」 ##「+ [動作]);」 起源永遠是它不應該的類。

對不起,如果這不明確。如果你需要更多的信息來幫助我,我更願意回答。

+1

對不起,JayCD我可能已經快速瀏覽了你的文章,但是有什麼問題嗎? (除了這個:字元素通常用於數組而不是ArrayList是正確的?) – bpgergo

+0

對不起,似乎解釋發生了什麼,但沒有真正問這個問題。我想知道如果我擴展一個類,爲什麼實例變量與我的超類中的變量相同。如果我不是騎馬,我會期待這一點,但我是。約翰下面說我做不到,這似乎支持我與這些班級的經驗。 – JayCD

回答

2

基本上問題是你試圖在子類中聲明額外的變量,就好像它們可以「覆蓋」超類中的變量一樣。變量不會以這種方式工作 - 它們不是多態的。

如果你需要給每個類的命中點不同的起始號,我建議你創建Entities一個protected構造函數(這應該改名,順便說一句 - 例如AbstractEntity)採取HP初始值(這或許應該改名爲hitPoints)。然後每個子類都有一個公共的構造函數來調用具有適當值的superconstructor。

例如:

public abstract class AbstractEntity { 
    private int hitPoints; 

    protected AbstractEntity(int initialHitPoints) { 
     this.hitPoints = initialHitPoints; 
    } 

    public int getHitPoints(){ 
     return hitPoints 
    } 

    void gainHitPoints(int amount) { 
     hitPoints += amount; 
    } 
} 

public class Monster extends AbstractEntity { 
    public Monster() { 
     // Every monster starts off with 4 hit points 
     super(4); 
    } 
} 

現在這只是一個改變的初始狀態的問題。如果希望的不同實體的行爲不同,則應該覆蓋子類中的抽象類方法。

+0

完美。我知道該怎麼做,以及如何避免該功能中的這個錯誤。 – JayCD

0

我相信你的問題是範圍界定。可從getHP訪問Entities *的HP *,但CharacterMonsterHP是碰巧具有相同名稱的不同變量。此外,將HP標記爲private意味着子類無法訪問該變量 - 我認爲您有protected

什麼可能是正確的解決方案,以擺脫怪物和字符惠普,使惠普實體保護,並設置默認的怪物和字符構造函數的默認惠普。

*以單數名稱命名對象是一種很好的風格,所以最好命名爲Entity

+0

謝謝。這給了我更多的信息。 – JayCD

0

如果我理解正確的話,問題如下:

你聲明的屬性HP在實體類私人和在子類中聲明一個新的變量(見其他答案)(!)。

您可以通過構造函數e設置HP來解決此問題。

class Entitites { 
    private int HP; 

    public Entities(int hp) { 
    this.HP = hp; 
    } 
} 

class Monster extends Entities { 
    public Monster() { 
    super(4); 
    } 
}