簡體   English   中英

Java:在自己的方法中引用類

[英]Java: Referring to a Class inside its own method

我正在做一個正在嘗試調試的任務。 我有很多error: (method name) in class (SuperClass Name) cannot be applied to given types; 該項目正在將針對過程編程的游戲改用於同一游戲,但現在針對OOP。 我是Java的新手,並負責創建許多類,其中有兩個是Superclass的子類(很明顯),並且為我提供了要使用的方法及其參數。 我遇到的問題是,子類中的一種方法應該控制玩家和敵人這兩個角色之間的戰斗。 這兩個類都是字符類(超類)的子類。 由於這是一個班級任務,因此我不想發布所有內容,但以下是我嘗試執行的戰斗方法的示例。 我遇到,並繼續在總體上有“ 繼承 ”的問題,就是究竟是什么父/子類,以及如何通過他們每個人之間存在一定的值/變量之間的繼承。

在下面的示例代碼中,此方法嵌套在擴展Character類的Player類中。 此方法需要使用Enemy類中的Enemy並執行其中的動作。 根據結果​​,我將布爾值傳遞回程序的main方法。

我的問題是 我不確定在本例中如何在已經包含在“ Player ”類下的方法內調用已成為“ Player ”類的類。 要求我在調用該方法時使用一個參數Enemy 我很肯定我沒有以適當的方式來處理這個特定的任務,並且有更好的方法來處理這個問題。 但是,非常感謝您了解所有可能的幫助,因為這將幫助我以正確的方式完成這項任務。

Player類的示例方法如下:

public abstract class Character{ //Character Superclass - attack method called

public int attack(Player _player){
    Random randomNumbers = new Random();
    int enemyRandAtk = randomNumbers.nextInt(Weapon.getMaxDamage - Weapon.getMinDamage) + Weapon.getMinDamage;
    int enemyAtk = enemyRandAtk + getStrength();
    int charRemainingHP = _player.getHitPoints() - enemyAtk; //can I call _player in the Character class????
    System.out.printf("%s attacks with ATK = %d + %d = %d\n", getName(), getStrength(), enemyRandAtk, enemyAtk);
    System.out.printf("%s HP is now %d - %d = %d\n\n", _player.getName(), _player.getHitPoints(), enemyAtk, charRemainingHP);
    return charRemainingHP;
}

public class Player extends Character{


  public int attack(Enemy _enemy){
    Random randomNumbers = new Random();
    int enemyHP = _enemy.getHitPoints();
    int charRandAtk = randomNumbers.nextInt(Weapon.getMaxDamage - Weapon.getMinDamage) + Weapon.getMinDamage;
    int charAtk = charRandAtk + getStrength();
    int enemyRemainingHP = _enemy.getHitPoints() - charAtk;
    System.out.printf("\n\n%s attacks with ATK = %d + %d = %d\n", getName(), getStrength(), charRandAtk, charAtk);
    System.out.printf("%s HP is now %d - %d = %d\n\n", _enemy.getName(), enemyHP, charAtk, enemyRemainingHP);
    return enemyRemainingHP;
  }
  public boolean battleWizard(Enemy _enemy){
    Random randomNumbers = new Random();
    Scanner userInput = new Scanner(System.in);
    int spellCast = randomNumbers.nextInt(4) + 1;
    System.out.printf("*** %s vs The Evil Wizard ***\n\n", getName()); //getName() is in Player Class
    boolean charWinning = false;
    int updWizHP = _enemy.getHitPoints(); //****** Question 1. below
    do{
        System.out.print("Choose your action: \n" +
                         "1. Attack\n" +
                         "2. Attempt Spell Cast\n\n" +
                         "What would you like to do?: ");
        int battleDecision = userInput.nextInt();

        if (battleDecision == 1){
            updWizHP = Player.attack(_enemy); //**** Question #2 Below
            if (updWizHP <= 0){
                charWinning = true;
                break;
            }
        }else if(battleDecision == 2){
            System.out.print("Enter your guess: ");
            int playerGuess = userInput.nextInt();
            if (playerGuess == spellCast){
                System.out.printf("The %s's spell is cast successfully!  The Wizard's HP is now 0!\n\n", getName());
                charWinning = true;
                updWizHP = 0;
                break;
            }else{
            System.out.print("Your spell missed the Wizard.  Now he attacks!\n");
            }
        }
        if (getHitPoints() > 0){
            enemyDamage = Enemy.attack();
            decreaseHitPoints(_enemy.attack(Player)); \\**** Question #3 below
            if (getHitPoints() < 0){
                charWinning = false;
                break;
            }
        }
    }while(getHitPoints() > 0 && _enemy.getHitPoints() > 0);

    if (charWinning)
        return true;
    else
        return false;
   }
  }

請記住,這是子類( Player )中的一種方法,它與( Enemy )具有大致相同的方法, Enemy這一個和其他幾個方法相同。

根據上面的代碼,這是我的具體問題:

  1. 方法battleWizard第6 battleWizard (注釋中的#1問題)-由於此方法位於Player類中,因此我可以以此方式引用Enemy類嗎? 如果沒有,有什么更好的方法?

  2. 方法battleWizard第12 battleWizard (注釋中的#2問題)-當方法(代碼示例)在類本身中時,如何引用以其自己的名稱創建對象的類? 我想接受最終用戶的播放player播放player並在自身內部引用該對象,如果這有意義嗎? 我試圖形象化地說明編譯器將如何執行此任務,並且無法想象這種工作方式。

  3. 從底部開始的13行(注釋中的#3問題參考):a)您可以將一個方法作為參數傳遞給Java中這樣的另一個方法嗎? b)像這樣調用另一個子類(與調用該類的子類相同的子類)的正確方法是可能的嗎?

感謝您的幫助。 如前所述,由於這是一個類分配,所以我不想提供更多代碼示例。 但不可避免的是,如果這有助於我理解,我會。 請讓我知道您需要什么進一步的信息。

預計到達時間:我添加了其他代碼來描述父類和子類之間的關系。 對於Enemy子類,攻擊方法依賴於Character超類。 因此,在上面的代碼示例中,我希望它能闡明3.b。 我的問題。 需要任何其他信息,請讓我知道。

由於定義了attack(Player _player) ,這意味着您只允許傳遞Player對象,但您正在使用像Player.attack(_enemy)這樣的方法,它意味着傳遞Enemy對象,因此會出現編譯錯誤。

您需要更正此問題。 閱讀我的段落“放在一邊……”。

方法warWizard中的第6行(注釋中的#1問題)-由於此方法位於Player類中,因此我可以以此方式引用Enemy類嗎? 如果沒有,有什么更好的方法?

根據您的代碼示例, int updWizHP = _enemy.getHitPoints(); 如果您想獲得敵人的生命值,這是一個有效而明智的電話。 _enemy是您的Enemy對象,您可以在該對象上使用任何方法,只要該方法存在於該類中即可。

方法warWizard中的第12行(注釋中的#2問題)-當方法(代碼示例)在類本身中時,如何引用以其自己的名稱創建對象的類? 我想接受最終用戶的播放器播放器,並在自身內部引用該對象,如果這有意義嗎? 我試圖形象化地說明編譯器將如何執行此任務,並且無法想象這種工作方式。

由於Player擴展了Character ,因此您將在Player類中繼承attack方法(可視化為在Character類中定義attack方法)。 因此,您實際上不需要使用updWizHP = Player.attack(_enemy); 但是您只需使用updWizHP = attack(_enemy); 但是,這是編譯錯誤,請閱讀答案的第一部分和最后一部分。

現在,由於attack方法不使用任何的實例字段Player類(的狀態Player類),所以你不必擔心,但如果是,那么你有沒有想過,並決定在其Player ,你想打電話給你的類對象attack方法。

從底部開始的13行(注釋中的#3問題參考):a)您可以將一個方法作為參數傳遞給Java中這樣的另一個方法嗎? b)像這樣調用另一個子類(與調用該類的子類相同的子類)的正確方法是可能的嗎?

  • 對於#3.a:使用decreaseHitPoints(_enemy.attack(Player)); 你是不是傳遞方法的另一種方法,但首先_enemy.attack(Player)將會被評估並為你的代碼的int將返回和值將被傳遞到decreaseHitPoints
  • 對於#3.b:您沒有調用任何子類,而是在對象上調用方法,則該對象表示的類是否位於繼承樹中都沒有關系。 您只需確保它是邏輯調用並且該方法存在於類中就可以了。 我猜_enemy.attack(Player)會給您編譯錯誤,因為您沒有將Player定義為對象引用變量。 您必須使用一些變量,不能使用這樣的類名。 最好使用_enemy.attack(this)


_enemy.attack(Player)這表明,在攻擊方法中,您想傳遞一個Player對象,現在您可以使用_enemy.attack(this) ,這意味着傳遞當前調用了battleWizard對象(有意義)或使用_enemy.attack(new Player())意味着創建一個Player類的新對象並傳遞該對象。


順便說一句 ,我想你最好定義public int attack(Player _player){作為public int attack(Character _character){因為這樣在將來你可以使用attack方法傳遞一個Enemy對象或某些子類的Character

那就是“繼承”“程序到接口”的美 我建議您搜索並了解這兩個概念。


可能沒有意識到的一些快速注釋這些是嘗試公開主題/概念的一般性注釋,可能會有更多的限制行為,因此請閱讀每個主題/概念的更多信息 ):

  • 對象是類的運行時表示。
  • 父類的方法由子類繼承,如果要從同一類進行調用,則無需使用對象即可調用它們。 將其可視化為在同一類中定義該方法( 有關上下文的更多信息,請參見上下文公共v / s受保護的v / s私有方法 )。
  • 您可以覆蓋繼承的方法。
  • 可以使用其任何子類的對象調用接受超類型的方法。 例如,在您的情況下, giveMeAnyCharacter(Character char)可以用作giveMeAnyCharacter(new Person())giveMeAnyCharacter(new Enemy())
  • 在Java中, this表示當前對象或實例,而super表示超類。 因此,可以創建一個新對象,或者如果您想使用與您正在使用的對象相同的對象,請使用this
  • 始終將所有通用代碼(方法或實例字段)放在超類中,並讓子類通過繼承利用它。

因此,Java對方法和字段(以及類)具有“可見性”,它定義了其他類確切可見的內容。 查找fe JLS 6.5.7.1-1,簡單方法名稱和可見性。

但是,在您的情況下,“不能應用於給定類型”意味着您將與簽名所說的參數類型不同的參數傳遞給方法。

不過,對於問題2,你只寫this.attack(_enemy)或者干脆attack(_enemy) (順便說一句,下划線是什么?我希望這是轉換產生的產物,而不是您的樣式指南中的內容)

問題3:只需使用_enemy.attack(this)

順便說一句,您混合使用了OO術語-一個遍歷類的實例。

您的問題尚不清楚,但是我認為問題在於您缺乏術語以及缺乏理解。 我會為您嘗試一些建議:

方法warWizard中的第6行-由於此方法位於Player類中,因此我可以以此方式引用Enemy類嗎? 如果沒有,有什么更好的方法?

int updWizHP = _enemy.getHitPoints(); //****** Question 1. below    

如果getHitPoints()Player類中,則不能使用Enemy 實例調用它。 字段和方法必須存在於調用中使用的實例的類或其繼承樹中(超類)。

如果getHitPoints()對於PlayerEnemy都是通用的,則應將方法放在兩個通用的最近的類中-在您的情況下,它將是Character類。 將方法放在Character類中(並賦予其保護性公共可見性),使其可以同時存在於Player類和Enemy類中(並使用Player和Enemy的關聯實例進行調用)

當方法(代碼示例)在類本身中時,如何引用以自己的名稱創建對象的類?

我可能無法想象您在這里描述的是this關鍵字(您的代碼中似乎沒有使用關鍵字)。 this表示您所在的類的當前實例。

因此,使用this.attack(_enemy)是如何使當前Player實例攻擊指定的敵人。

a)您可以將一個方法作為參數傳遞給Java中這樣的另一個方法嗎? b)像這樣調用另一個子類(與調用該類的子類相同的子類)的正確方法是可能的嗎?

a)否。Java不允許將方法作為參數傳遞。 如果要傳遞方法,則必須將一個實例 (包含該方法的類)作為變量傳遞(例如x ),然后將要執行的方法稱為x.method() 您正在做的是調用方法並將返回值用作參數 ,這是完全允許的。

decreaseHitPoints(_enemy.attack); // passing a method - not allowed
decreaseHitPoints(_enemy.attack(Player)); // passing a return value from calling a method - OK

b)我想你想要的是this.decreaseHitPoints(_enemy.attack(this)); 是的,你可以(也應該)在其他類調用方法-但如果你調用的類是無關的(即不是從繼承),你只能調用這些方法,如果他們已經宣布與公眾知名度。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM