【问题标题】:Java: Referring to a Class inside its own methodJava:在自己的方法中引用一个类
【发布时间】:2016-02-16 07:06:29
【问题描述】:

我正在处理我目前正在尝试调试的任务。我有很多error: (method name) in class (SuperClass Name) cannot be applied to given types;。该项目正在将一个以过程编程为中心的游戏重新用于同一游戏,但现在围绕 OOP。我是 Java 新手,我的任务是创建许多类,其中两个是超类的子类(显然),并且我已经获得了要拥有的方法及其参数。我遇到的问题是子类中的一种方法应该控制两个角色之间的战斗,玩家和敌人。这两个类都是字符类(超类)的子类。由于这是一项课堂作业,我不想发布我拥有的所有内容,但下面是我尝试执行的战斗方法的示例。我遇到的问题,一般来说,“inheritance”仍然存在,正是在父/子类之间继承了什么以及如何传递某些值/变量他们每个人之间。

在下面的示例代码中,此方法嵌套在扩展 Character 类的 Player 类中。此方法需要使用 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) 的方法大致相同,只是除了这个和其他几个。

就我上面的代码而言,这是我的具体问题:

  1. 方法battleWizard 中的第6 行(注释中的#1 问题)- 由于此方法位于Player 类中,我可以以这种方式引用Enemy 类吗?如果没有,有什么更好的方法?

  2. 方法battleWizard 中的第12 行(注释中的#2 问题)- 当方法(代码示例)在类本身中时,如何引用具有以自己的名称创建的对象的类?我想使用最终用户的播放器player 并在其内部引用该对象,如果这有意义吗?我正在尝试想象编译器将如何执行此任务并且无法想象它会如何工作。

  3. 从底部算起 13 行(注释中的#3 问题参考): a)您可以将方法作为参数传递给Java中的另一个方法吗? b)是像这样调用另一个子类(与调用该类的子类级别相同)的正确方法,还是有可能?

感谢您的帮助。正如我之前提到的,由于这是一个班级作业,我不想提供更多我的代码示例。但不可避免地,如果它有助于我理解,那么我会的。请让我知道您需要什么进一步的信息。

预计到达时间: 我添加了额外的代码来描述超类和子类之间的关系。对于Enemy 子类,它依赖于Character 超类的攻击方法。所以在我上面的代码示例中,我希望它能阐明 3.b。我的问题。需要任何进一步的信息,请告诉我。

【问题讨论】:

  • 理想情况下,与其向我们展示更多实际代码,不如创建一个简短但完整的示例来说明只是问题。你可以通过复制你的真实代码来做到这一点,并一点一点地删除所有不相关的东西,确保你仍然有错误。它不需要做任何有用的事情——它只需要以我们可以重现的方式来展示问题。
  • 告诉行号无济于事,因为文本编辑器的格式和所有..请评论代码类似#question1#question3.a#question3.b ..您当前尝试将代码注释是不是很有帮助..
  • 你不用上课。你调用方法。从其他方法调用它们是正常的。你的问题,或者至少你的标题,仍然不清楚。
  • 我已经编辑了我的线程以适应上面的所有问题/cmets。感谢您最初的意见,帮助我缩小问题范围!
  • "在这个例子中,如何在一个已经包含在"Player"类下的方法中调用一个已经成为"Player"类的类"仍然没有意义。

标签: java inheritance methods subclass superclass


【解决方案1】:

您收到编译错误,因为您定义了attack(Player _player),这意味着您只允许传递Player 对象,但您使用的是Player.attack(_enemy),这意味着传递Enemy 对象。

您需要更正此问题。阅读我的段落,“顺便说一句……”。

方法battleWizard中的第6行(注释中的#1问题)-因为这个 方法驻留在 Player 类中,我可以引用 Enemy 类吗 这边走?如果没有,有什么更好的方法?

根据您的代码示例,如果您想获取敌人的生命值,int updWizHP = _enemy.getHitPoints(); 是一个有效且明智的调用。 _enemy 是您的 Enemy 对象,只要该类中存在该方法,您就可以对其使用任何方法。

方法 BattleWizard 中的第 12 行(笔记中的#2 问题)- 我该怎么做 引用具有以自己的名称创建的对象的类 方法(代码示例)在类本身中?我想采取 最终用户的播放器播放器并在其内部引用该对象,如果 这就说得通了?我试图想象编译器将如何 执行此任务,无法想象这会奏效。

由于PlayerCharacter 的扩展,因此您将在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 对象或@ 的某个子类987654357@

这就是“继承”“程序到接口”的美妙之处。我建议您搜索并了解这两个概念。


为您提供一些快速说明,您可能会知道(这些是试图公开主题/概念的一般说明,可能会有更多限制行为,因此请阅读有关每个主题的更多信息/概念):
  • 对象是类的运行时表示。
  • 超类的方法由子类继承,如果从同一个类调用,则无需使用对象来调用它们。将其可视化为在同一个类中定义该方法(阅读更多关于在上下文公共 v/s 受保护 v/s 私有方法中的继承)。
  • 您可以覆盖继承的方法。
  • 可以使用其任何子类的对象调用接受超类型的方法。例如,在您的情况下,giveMeAnyCharacter(Character char) 可以用作giveMeAnyCharacter(new Person())giveMeAnyCharacter(new Enemy())
  • 在 Java 中,this 表示当前对象或实例,super 表示超类。因此,要么创建一个新对象,要么如果您想使用您正在展示的同一对象,请使用this
  • 始终将所有通用代码(方法或实例字段)放在超类中,并让子类通过继承利用它。

【讨论】:

  • 很好的回应!非常感谢。由于您建议我在方法参数中使用this,您的建议是否要求我为超类中的所有变量输入this.(variable)
  • 在 Java 中,this 仅表示当前对象或当前实例 .. 从逻辑意义上讲,将 this 视为当前上下文 .. 当您说 _enemy.attack(Player) 时,这表明在 @987654369 @ 方法你想传递一个Player 对象,现在要么使用_enemy.attack(this),这意味着传递当前正在调用battleWizard 的对象(有意义),要么使用_enemy.attack(new Player),这意味着创建一个@ 的新对象987654374@类。
  • 干得好!和其他所有人。我希望我能给每个人一个加分的答案,但你们都帮助了我!!!非常感谢您,因为您不知道您提供了多少帮助!
  • @hagrawal 你能为未来的读者改进你的笔记吗? 父类的所有方法都被子类继承 不正确。只有声明为 protectedpublic 的方法会被继承。 你不需要使用对象... 也是不真实的。除非方法是 static,否则您确实需要一个对象 - 只是该对象通常是隐含的 this 实例。
  • @adelphus 感谢您的评论,伙计,这些是我提到的更广泛的观点,以揭示概念/主题,所以没有什么比不真实的,因为每一步总是有更多的限制行为,我添加了一个注释覆盖它。
【解决方案2】:

您的问题很不清楚,但我认为问题在于您缺乏术语以及缺乏理解。我会为你尝试一些指针:

方法 BattleWizard 中的第 6 行 - 由于此方法位于 Player 类,我可以这样引用 Enemy 类吗?如果不, 有什么更好的方法?

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

如果getHitPoints() 属于Player 类,则不能使用Enemy 调用它实例。字段和方法必须存在于调用中使用的实例的类中,或其继承树(超类)中。

如果getHitPoints()PlayerEnemy 都是通用的,您应该将该方法放在最近的两个通用类中 - 在您的情况下,它将是Character 类。将该方法放在 Character 类中(并赋予其 protectedpublic 可见性)允许它同时存在于 PlayerEnemy 类中(并使用Player 和 Enemy 的关联实例)

如何引用一个在它自己的对象中创建的类 方法(代码示例)在类本身时的名称?

我可以想象您在这里描述的唯一内容是 this 关键字(您似乎没有在代码中使用它)。 this 代表你所在类的当前实例。

所以使用this.attack(_enemy) 是让当前Player 实例攻击指定敌人的方法。

a) 你能把一个方法作为参数传递给另一个方法吗? 爪哇? b) 是调用另一个子类(同一个子类)的正确方法 水平作为调用班级的人)这样还是有可能?

a) 不可以。Java 不允许将方法作为参数传递。如果你想传递一个方法,你必须传递一个instance(一个包含该方法的类)作为变量——比如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));。是的,您可以(并且应该)调用其他类中的方法 - 但如果您的调用类是不相关的(即不继承自),则您只能在它们已声明为具有 public 可见性的情况下调用这些方法。

【讨论】:

  • 我爱你和你残酷的诚实! (灯泡真的在我脑海里熄灭了)。我在我的超类中知道this.(variable),但从未真正理解它的含义。不想拖着 cmets/questions,但我是否需要在超类中输入 this,或者我可以在任何子类中输入它并且 this 指向该子类的特定变量?
  • 在 Java 中没有什么是必需的,但this 可以而且应该在任何可以使用的地方使用。通过编写this,您的意图很明确,即您正在引用this 字在其中键入的类的当前实例。如果你在子类中使用this,你指的是子类。如果你在超类中使用this,你指的是超类。
  • 非常感谢您的澄清。现在我完全明白了
【解决方案3】:

因此,Java 对方法和字段(以及类)具有“可见性”,它定义了对其他类究竟可见的内容。查找 f.e. JLS 6.5.7.1-1,简单方法名称和可见性。

但是,在您的情况下,“不能应用于给定类型”意味着您传递给方法的参数类型与签名所说的不同。

不过,对于问题 2,您只需写 this.attack(_enemy),或直接写为 attack(_enemy)。 (顺便说一句,下划线是什么?我希望它是转换的产物,而不是你的风格指南中的东西)

问题 3:使用_enemy.attack(this)

顺便说一句,您的 OO 术语混淆了 - 一个传递类的实例。

【讨论】:

  • 非常感谢您的回复塔索斯。我相信我理解您的回答,并将按照您的建议工作。哦,下划线只是我在方法中添加参数的方式,例如 enemy 在这种情况下。当我这样做时,我会在传递的参数之前加上一个下划线来跟踪事情,如果这有意义吗?
猜你喜欢
  • 2013-07-10
  • 1970-01-01
  • 2018-10-19
  • 1970-01-01
  • 1970-01-01
  • 2016-06-03
  • 2011-07-13
  • 2015-04-21
  • 1970-01-01
相关资源
最近更新 更多