简体   繁体   English

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

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

I am working on an assignment that I'm trying to debug currently. 我正在做一个正在尝试调试的任务。 I have numerous error: (method name) in class (SuperClass Name) cannot be applied to given types; 我有很多error: (method name) in class (SuperClass Name) cannot be applied to given types; . The project is repurposing a game centered around Procedural programming to the same game, but now around OOP. 该项目正在将针对过程编程的游戏改用于同一游戏,但现在针对OOP。 I'm new to Java and have been tasked with creating numerous Classes, two of which are subclasses to a Superclass (obviously), and I have been given what methods to have and their parameters. 我是Java的新手,并负责创建许多类,其中有两个是Superclass的子类(很明显),并且为我提供了要使用的方法及其参数。 The problem I am having is that one method in a subclass is supposed to control a battle between two characters, the player and an enemy. 我遇到的问题是,子类中的一种方法应该控制玩家和敌人这两个角色之间的战斗。 Both of these classes are the subclass to the character class (superclass). 这两个类都是字符类(超类)的子类。 Since this is a class assignment, I don't want to post everything that I have, but below is an example of the battle method I'm trying to perform. 由于这是一个班级任务,因此我不想发布所有内容,但以下是我尝试执行的战斗方法的示例。 The problem I'm experiencing, and continue to have with " inheritance " in general, is exactly what is inherited between parent/child classes and how to pass certain values/variables between each of them. 我遇到,并继续在总体上有“ 继承 ”的问题,就是究竟是什么父/子类,以及如何通过他们每个人之间存在一定的值/变量之间的继承。

In the example code below, this method is nested within the Player class that extends a Character class. 在下面的示例代码中,此方法嵌套在扩展Character类的Player类中。 This method needs to use and enemy from the Enemy class and perform the actions within. 此方法需要使用Enemy类中的Enemy并执行其中的动作。 Depending on the outcome, I pass back a boolean to the main method of my program. 根据结果​​,我将布尔值传递回程序的main方法。

My problem is this; 我的问题是 I'm unsure how to call a class that has been made " Player " class in this example, within a method that is already contained under the " Player " class. 我不确定在本例中如何在已经包含在“ Player ”类下的方法内调用已成为“ Player ”类的类。 I was asked to use one argument for the method when called, Enemy . 要求我在调用该方法时使用一个参数Enemy I'm positive that I'm not approaching this particular assignment in the appropriate way and there is a much better way to deal with this. 我很肯定我没有以适当的方式来处理这个特定的任务,并且有更好的方法来处理这个问题。 But any help to understand what is possible is much appreciated as it will help me approach this assignment in the correct way. 但是,非常感谢您了解所有可能的帮助,因为这将帮助我以正确的方式完成这项任务。

Sample Method from the Player class is as follows: 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;
   }
  }

Please keep in mind that this is a method within a subclass ( Player ) that holds roughly the same methods as ( Enemy ) short of this one and a few others. 请记住,这是子类( Player )中的一种方法,它与( Enemy )具有大致相同的方法, Enemy这一个和其他几个方法相同。

In terms of my code above, here are my specific questions: 根据上面的代码,这是我的具体问题:

  1. Line 6 in method battleWizard (#1 Question in notes) - Since this method resides in the Player class, can I reference the Enemy class in this way? 方法battleWizard第6 battleWizard (注释中的#1问题)-由于此方法位于Player类中,因此我可以以此方式引用Enemy类吗? If not, what is a better way of doing so? 如果没有,有什么更好的方法?

  2. Line 12 in method battleWizard (#2 Question in notes) - How can I reference a class that has an object created in it's own name when the method (code example) is in the class itself? 方法battleWizard第12 battleWizard (注释中的#2问题)-当方法(代码示例)在类本身中时,如何引用以其自己的名称创建对象的类? I'd like to take the end-user's player player and reference that object within itself, if that makes sense? 我想接受最终用户的播放player播放player并在自身内部引用该对象,如果这有意义吗? I am trying to visualize how the compiler will perform this task and can't imagine this ever working. 我试图形象化地说明编译器将如何执行此任务,并且无法想象这种工作方式。

  3. 13 Lines from the bottom (#3 Question reference in notes): a) can you pass a method as a parameter to another method like this in Java? 从底部开始的13行(注释中的#3问题参考):a)您可以将一个方法作为参数传递给Java中这样的另一个方法吗? b) is the proper way to invoke another subclass (same subclass level as the one calling the class) like this or is it even possible? b)像这样调用另一个子类(与调用该类的子类相同的子类)的正确方法是可能的吗?

Thank you for the help. 感谢您的帮助。 As I mentioned before, since this is a class assignment I'd prefer not to provide more samples of my code. 如前所述,由于这是一个类分配,所以我不想提供更多代码示例。 But inevitably, if it helps me to understand then I will. 但不可避免的是,如果这有助于我理解,我会。 Please let me know what further information you need. 请让我知道您需要什么进一步的信息。

ETA: I added additional code to portray the relationship between the super and subclasses. 预计到达时间:我添加了其他代码来描述父类和子类之间的关系。 For the Enemy subclass, it relies on the Character superclass for the attack method. 对于Enemy子类,攻击方法依赖于Character超类。 So in my code example above, I hope that it clarifies 3.b. 因此,在上面的代码示例中,我希望它能阐明3.b。 of my question. 我的问题。 Any further information required, please let me know. 需要任何其他信息,请让我知道。

You are getting compilation errors because you defined attack(Player _player) which means you are allowing only Player objects to be passed but you are using like Player.attack(_enemy) which means passing Enemy object. 由于定义了attack(Player _player) ,这意味着您只允许传递Player对象,但您正在使用像Player.attack(_enemy)这样的方法,它意味着传递Enemy对象,因此会出现编译错误。

You need to correct this. 您需要更正此问题。 Read my para, "As an aside...". 阅读我的段落“放在一边……”。

Line 6 in method battleWizard (#1 Question in notes) - Since this method resides in the Player class, can I reference the Enemy class in this way? 方法warWizard中的第6行(注释中的#1问题)-由于此方法位于Player类中,因此我可以以此方式引用Enemy类吗? If not, what is a better way of doing so? 如果没有,有什么更好的方法?

As per your code sample, int updWizHP = _enemy.getHitPoints(); 根据您的代码示例, int updWizHP = _enemy.getHitPoints(); is a valid and sensible call if you want to get the hit points of the enemy. 如果您想获得敌人的生命值,这是一个有效而明智的电话。 _enemy is your Enemy object and you can all any method on it as long as that method exists in that class. _enemy是您的Enemy对象,您可以在该对象上使用任何方法,只要该方法存在于该类中即可。

Line 12 in method battleWizard (#2 Question in notes) - How can I reference a class that has an object created in it's own name when the method (code example) is in the class itself? 方法warWizard中的第12行(注释中的#2问题)-当方法(代码示例)在类本身中时,如何引用以其自己的名称创建对象的类? I'd like to take the end-user's player player and reference that object within itself, if that makes sense? 我想接受最终用户的播放器播放器,并在自身内部引用该对象,如果这有意义吗? I am trying to visualize how the compiler will perform this task and can't imagine this ever working. 我试图形象化地说明编译器将如何执行此任务,并且无法想象这种工作方式。

Since Player is extending Character , so you would have attack method inherited in Player class (visualize this is as defining attack method in Character class). 由于Player扩展了Character ,因此您将在Player类中继承attack方法(可视化为在Character类中定义attack方法)。 So, you really don't need to use updWizHP = Player.attack(_enemy); 因此,您实际上不需要使用updWizHP = Player.attack(_enemy); but you can simply use updWizHP = attack(_enemy); 但是您只需使用updWizHP = attack(_enemy); . However, this is a compilation error, read my first and last portion of answer. 但是,这是编译错误,请阅读答案的第一部分和最后一部分。

Now, since attack method is not using any instance field of Player class (state of the Player class) so you need not to worry but if it was then you had to think and decide that on which Player class object you want to call your attack method. 现在,由于attack方法不使用任何的实例字段Player类(的状态Player类),所以你不必担心,但如果是,那么你有没有想过,并决定在其Player ,你想打电话给你的类对象attack方法。

13 Lines from the bottom (#3 Question reference in notes): a) can you pass a method as a parameter to another method like this in Java? 从底部开始的13行(注释中的#3问题参考):a)您可以将一个方法作为参数传递给Java中这样的另一个方法吗? b) is the proper way to invoke another subclass (same subclass level as the one calling the class) like this or is it even possible? b)像这样调用另一个子类(与调用该类的子类相同的子类)的正确方法是可能的吗?

  • For #3.a: Using decreaseHitPoints(_enemy.attack(Player)); 对于#3.a:使用decreaseHitPoints(_enemy.attack(Player)); you are not passing method to another method BUT first _enemy.attack(Player) will be evaluated and as your code an int would be returned and that value will be passed to decreaseHitPoints . 你是不是传递方法的另一种方法,但首先_enemy.attack(Player)将会被评估并为你的代码的int将返回和值将被传递到decreaseHitPoints
  • For #3.b: You are not invoking any sub-class but you are calling method on a object, it doesn't matter if the class that object represent lies in the inheritance tree or not. 对于#3.b:您没有调用任何子类,而是在对象上调用方法,则该对象表示的类是否位于继承树中都没有关系。 Only thing you need to make sure that it is a logical call and that method exists in the class. 您只需确保它是逻辑调用并且该方法存在于类中就可以了。 I guess _enemy.attack(Player) will give you compilation error because you are not defining Player as an object reference variable. 我猜_enemy.attack(Player)会给您编译错误,因为您没有将Player定义为对象引用变量。 You have to use some variable, cannot use class name like this. 您必须使用一些变量,不能使用这样的类名。 Better use _enemy.attack(this) 最好使用_enemy.attack(this)


_enemy.attack(Player) this suggests that in attack method you want to pass an Player object, now either you use _enemy.attack(this) which means pass on current object on which battleWizard is getting called (make sense) or use _enemy.attack(new Player()) which means create a new object of Player class and pass that one. _enemy.attack(Player)这表明,在攻击方法中,您想传递一个Player对象,现在您可以使用_enemy.attack(this) ,这意味着传递当前调用了battleWizard对象(有意义)或使用_enemy.attack(new Player())意味着创建一个Player类的新对象并传递该对象。


As an aside , I think you better be defining public int attack(Player _player){ as public int attack(Character _character){ because like this in future you can use attack method to pass an Enemy object or some sub-class of Character 顺便说一句 ,我想你最好定义public int attack(Player _player){作为public int attack(Character _character){因为这样在将来你可以使用attack方法传递一个Enemy对象或某些子类的Character

That's the beauty of "Inheritance" and "Program to interface" . 那就是“继承”“程序到接口”的美 I would recommend you to search and learn about these 2 concepts. 我建议您搜索并了解这两个概念。


Few quick notes for you , may be you will be aware ( these are general notes trying to expose the topic/concept, there could be more limiting behavior, so please read more on each topic/concept ): 可能没有意识到的一些快速注释这些是尝试公开主题/概念的一般性注释,可能会有更多的限制行为,因此请阅读每个主题/概念的更多信息 ):

  • An object is a runtime representation of a class. 对象是类的运行时表示。
  • Methods of super class are inherited by sub-class, and to call them you need not to use an object, if you are calling from same class. 父类的方法由子类继承,如果要从同一类进行调用,则无需使用对象即可调用它们。 Visualize this as defining that method in same class ( read more on inheritance in context public v/s protected v/s private methods ). 将其可视化为在同一类中定义该方法( 有关上下文的更多信息,请参见上下文公共v / s受保护的v / s私有方法 )。
  • You can override the inherited methods. 您可以覆盖继承的方法。
  • A method accepting a super type can be invoked with object of any of its subclass. 可以使用其任何子类的对象调用接受超类型的方法。 For example, in your case giveMeAnyCharacter(Character char) can be used as giveMeAnyCharacter(new Person()) or giveMeAnyCharacter(new Enemy()) . 例如,在您的情况下, giveMeAnyCharacter(Character char)可以用作giveMeAnyCharacter(new Person())giveMeAnyCharacter(new Enemy())
  • In Java this means current object or instance and super means super class. 在Java中, this表示当前对象或实例,而super表示超类。 So, either create a new object or if you want to use the same object on which you are presenting working then use this . 因此,可以创建一个新对象,或者如果您想使用与您正在使用的对象相同的对象,请使用this
  • Always put your all common code (method or instance fields) in super class and let sub-classes take advantage of it using inheritance. 始终将所有通用代码(方法或实例字段)放在超类中,并让子类通过继承利用它。

So, Java has "visibility" for methods and fields (and classes too), that defines what exactly is visible to an other class. 因此,Java对方法和字段(以及类)具有“可见性”,它定义了其他类确切可见的内容。 Look up fe JLS 6.5.7.1-1, Simple Method Names and Visibility. 查找fe JLS 6.5.7.1-1,简单方法名称和可见性。

However, in your case "cannot be applied to given types" implies that you pass to a method different parameter types than what the signature says. 但是,在您的情况下,“不能应用于给定类型”意味着您将与签名所说的参数类型不同的参数传递给方法。

Still, for question 2, you just write this.attack(_enemy) , or simply attack(_enemy) . 不过,对于问题2,你只写this.attack(_enemy)或者干脆attack(_enemy) (BTW, what's with the underscores? I hope it's an artifact from the conversion and not something in your style guide) (顺便说一句,下划线是什么?我希望这是转换产生的产物,而不是您的样式指南中的内容)

Question 3: just use _enemy.attack(this) . 问题3:只需使用_enemy.attack(this)

BTW, you have your OO terminology mixed up - one passes instances of classes around. 顺便说一句,您混合使用了OO术语-一个遍历类的实例。

Your question is quite unclear, but I think the problem is your lack of terminology as well as a lack of understanding. 您的问题尚不清楚,但是我认为问题在于您缺乏术语以及缺乏理解。 I'll try a few pointers for you: 我会为您尝试一些建议:

Line 6 in method battleWizard - Since this method resides in the Player class, can I reference the Enemy class in this way? 方法warWizard中的第6行-由于此方法位于Player类中,因此我可以以此方式引用Enemy类吗? If not, what is a better way of doing so? 如果没有,有什么更好的方法?

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

If getHitPoints() is in the Player class, you cannot call it with an Enemy instance . 如果getHitPoints()Player类中,则不能使用Enemy 实例调用它。 Fields and methods must exist in the classes of the instance being used in the call, or in their inheritance tree (super classes). 字段和方法必须存在于调用中使用的实例的类或其继承树中(超类)。

If getHitPoints() is both common to both Player and Enemy , you should place the method in the nearest class common to both - in your case, it would be the Character class. 如果getHitPoints()对于PlayerEnemy都是通用的,则应将方法放在两个通用的最近的类中-在您的情况下,它将是Character类。 Putting the method in the Character class (and giving it protected or public visibility) allows it to exist in both Player and Enemy classes (and to be called using associated instances of Player and Enemy) 将方法放在Character类中(并赋予其保护性公共可见性),使其可以同时存在于Player类和Enemy类中(并使用Player和Enemy的关联实例进行调用)

How can I reference a class that has an object created in it's own name when the method (code example) is in the class itself? 当方法(代码示例)在类本身中时,如何引用以自己的名称创建对象的类?

The only thing I can possibly imagine you describing here is the this keyword (which you don't seem to be using in your code). 我可能无法想象您在这里描述的是this关键字(您的代码中似乎没有使用关键字)。 this represents the current instance of the class you are in. this表示您所在的类的当前实例。

So using this.attack(_enemy) is how you would get the current Player instance to attack the specified enemy. 因此,使用this.attack(_enemy)是如何使当前Player实例攻击指定的敌人。

a) can you pass a method as a parameter to another method like this in Java? a)您可以将一个方法作为参数传递给Java中这样的另一个方法吗? b) is the proper way to invoke another subclass (same subclass level as the one calling the class) like this or is it even possible? b)像这样调用另一个子类(与调用该类的子类相同的子类)的正确方法是可能的吗?

a) No. Java does not allow methods to be passed as parameters. a)否。Java不允许将方法作为参数传递。 If you want to pass a method, you must pass an instance (of a class containing the method) as a variable - say x - and then call the method you want to execute as x.method() . 如果要传递方法,则必须将一个实例 (包含该方法的类)作为变量传递(例如x ),然后将要执行的方法称为x.method() What you are doing is calling a method and using the return value as a parameter which is perfectly allowed. 您正在做的是调用方法并将返回值用作参数 ,这是完全允许的。

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

b) I think what you want is this.decreaseHitPoints(_enemy.attack(this)); b)我想你想要的是this.decreaseHitPoints(_enemy.attack(this)); . Yes, you can (and should) call methods in other classes - but if your calling class is unrelated (ie not inherited from), you can only call those methods if they have been declared with public visibility. 是的,你可以(也应该)在其他类调用方法-但如果你调用的类是无关的(即不是从继承),你只能调用这些方法,如果他们已经宣布与公众知名度。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM