2009-11-22 42 views
-3

好吧,這已經有一段時間了,但我正在考慮重新編程。從它自己的類中取出變量數據,而不是它的子類,即使從子類中調用

無論如何,即使從子類調用,此代碼也會從它自己的類中取得變量數據,而不是它的子類。我如何得到它,因此它在兒童調用時使用兒童的變量數據而不是它自己的變量數據?

public class TestRPG1 { 

     static Player hero; 
     static Enemy dragon; 

     public static void main(String[] args) { 
      hero = new Player(); 
      dragon = new Enemy(); 

      while(dragon.hp > 0){ 
       int choice = (int) (Math.random() * 2); 

       if(choice == 0) 
        hero.attack(dragon); 

       else 
        hero.magic(dragon); 
      } 

      System.exit(0); 

     } 

    } 




    public class Combatant { 
     int hp = 100; 
     int mp = 100; 
     int attack = 15; 
     int magic = 25; 
     int defence = 15; 
     int damage = 0; 
     String name = "null"; 

     public void attack(Combatant target){ 
      damage = (int) (Math.random() * attack); 
      System.out.println(name + " attacked the " + target.name + " for " + damage + " damage!"); 
      target.hp -= damage; 
      System.out.println(target.name + " has " + target.hp + " HP left!"); 
     } 

     public void magic(Combatant target){ 
      damage = (int) (Math.random() * magic); 
      System.out.println(name + " shot a fireball at " + target.name + " for " + damage + " damage!"); 
      target.hp -= damage; 
      System.out.println(target.name + " has " + target.hp + " HP left!"); 
     } 

} 


public class Enemy extends Combatant{ 
    String name = "Dragon"; 
} 


public class Player extends Combatant{ 
    String name = "Hero"; 
} 
+0

爲什麼你有Combatant中的'damage'屬性。你也可以在你的兩個方法中創建這個int。這看起來不合邏輯,因爲你只是使用這個變量來降低目標的HP值,這不是來自Combatant的真實屬性。 你可以簡單地在你的方法中做這個變量。 – 2009-11-22 08:05:13

回答

0

屬性我編輯我的職務,這樣你就可以再次檢查這一點(如果你想)。 我混淆了名字,對不起。

您必須在Combatant類中使用構造函數,以便您可以調用您的超類構造函數。你的代碼看起來像;

public class Combatant { 

    public Combatant(String name) 
    { 
     this.name = name; 
    } 

    int hp = 100; 
    int mp = 100; 
    int attack = 15; 
    int magic = 25; 
    int defence = 15; 
    int damage = 0; 
    String name = "null"; 

    public void attack(Combatant target){ 
      damage = (int) (Math.random() * attack); 
      System.out.println(name + " attacked the " + target.name + " for " + damage + " damage!"); 
      target.hp -= damage; 
      System.out.println(target.name + " has " + target.hp + " HP left!"); 
    } 

    public void magic(Combatant target){ 
      damage = (int) (Math.random() * magic); 
      System.out.println(name + " shot a fireball at " + target.name + " for " + damage + " damage!"); 
      target.hp -= damage; 
      System.out.println(target.name + " has " + target.hp + " HP left!"); 
    } 

} 

public class Enemy extends Combatant{ 
    public Enemy() 
    { 
     super("Dragon"); 
    } 
} 

public class Player extends Combatant{ 
    public Player() 
    { 
     super("Hero"); 
    } 
} 


您還可以在戰鬥中添加的構造函數,如:

// A constructor to set the name and change the default magic. 
public Combatant(String name, int magic) 
{ 
    this.name = name; 
    this.magic = magic; 
} 

,然後你可以在敵人類寫這篇文章,使龍強。

public class Enemy extends Combatant 
{ 
    public Enemy() 
    { 
     super("Dragon", 30); 
    } 
} 

希望這有助於。

+0

謝謝,但那並沒有解決我的問題。 – William 2009-11-22 08:04:07

+4

除外。 – 2009-11-22 08:24:01

0

固定。

public class Enemy extends Combatant{ 
    Enemy(){ 
     name = "Dragon"; 
    } 
} 

public class Player extends Combatant{ 
    Player(){ 
     name = "Hero"; 
    } 
} 
0

我已經在javagaming.org中回答了您的問題,請檢查。

我認爲,在你這樣做的過程中,你隱藏父數據成員和父數據成員,而父數據成員卻被父母的方法調用,所以父數據成員被調用。

public class Enemy extends Combatant{ 
    public Enemy() { name = "Dragon"; } 
} 
public class Player extends Combatant{ 
    public Player() { name = "Hero"; } 
} 
0

您已經定義的實例在Combatant變量name。因此EnemyPlayer繼承這個變量。你不需要重新聲明它。一些其他的答案也是有效的,更好的編碼實踐。如果您不想更改代碼以使用set/get方法或使用構造函數,則可以使用稱爲初始化塊。在初始化塊中編寫的代碼在創建類的實例時由java執行。

public class Enemy extends Combatant { 
    { name = "Dragon"; } 
} 

public class Player extends Combatant { 
    { name = "Hero"; } 
} 

但請注意,這也可能有一些意想不到的副作用。例如考慮你這樣宣佈Enemy2,並在TestRPG1而不是Enemy中使用它。

public class Enemy2 extends Enemy { 
} 

.... 
dragon = new Enemy2(); 
.... 

你期望程序輸出什麼? nullDragon作爲名稱?它會輸出Dragon。爲什麼?因爲初始化塊也是爲子類構造函數執行的。

2

您的代碼輸出:

null shot a fireball at null for 1 damage! 
null has 99 HP left! 
null attacked the null for 7 damage! 
null has 92 HP left! 
...etc 

adon_y_coya的建議產出:

Hero shot a fireball at Dragon for 15 damage! 
Dragon has 85 HP left! 
Hero shot a fireball at Dragon for 13 damage! 
Dragon has 72 HP left! 
...etc 

Martijin Courteaux的建議產出:

Hero attacked the Dragon for 5 damage! 
Dragon has 95 HP left! 
Hero shot a fireball at Dragon for 12 damage! 
Dragon has 83 HP left! 
...etc 

Bozho的建議產出:

Hero shot a fireball at Dragon for 1 damage! 
Dragon has 99 HP left! 
Hero shot a fireball at Dragon for 3 damage! 
Dragon has 96 HP left! 
...etc 

抖動的建議產出:

Hero shot a fireball at Dragon for 17 damage! 
Dragon has 83 HP left! 
Hero attacked the Dragon for 14 damage! 
Dragon has 69 HP left! 
...etc 

威廉的建議是完全一樣adon_y_coya的。

所以,看來你有不低於公佈答案,包括不同的方式來做到這一點。然而,你還沒有接受一個單一的答案,你似乎認爲這個話題充滿了trolls,並且無益。但我認爲真正的問題是,你只是不明白你在做什麼,至少在繼承方面。 你是shadowing你的名字變量,所以子類的名稱變量和父類的名字變量是兩個不同的變量。您正在引用Combatant.name,它與Enemy.name和Player.name不同,因爲您是投影。這導致我爲你提供了另一種可能的「解決方案」,雖然它只是一個指標,你首先做錯了。

public void attack(Combatant target) 
{ 
     damage = (int) (Math.random() * attack); 
     System.out.println(((this instanceof Player) ? ((Player)this).name : ((Enemy)this).name) + " attacked the " + ((target instanceof Player) ? ((Player)target).name : ((Enemy)target).name) + " for " + damage + " damage!"); 
     target.hp -= damage; 
     System.out.println(((target instanceof Player) ? ((Player)target).name : ((Enemy)target).name) + " has " + target.hp + " HP left!"); 
} 

該方法給出了正確的輸出,但顯然完全消除了類繼承的目的。 adon_y_coya的建議是正確的,因爲它正確地利用了繼承。

並且不要告訴我我的建議不起作用。因爲,如Joonas Pulakka如此巧妙地指出,兩次,建議工作。如果你仍然發現它們存在問題,那麼這是因爲你不太瞭解Java的繼承關係 - 所以去找一本Java書並閱讀它,因爲你的理解不夠紮實,無法繼承。這就是爲什麼你有-2;人們覺得你應該在開始詢問其他人之前學習更多。

相關問題