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;
. The project is repurposing a game centered around Procedural programming to the same game, but now around 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. 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. This method needs to use and enemy from the Enemy
class and perform the actions within. Depending on the outcome, I pass back a boolean to the main method of my program.
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. I was asked to use one argument for the method when called, 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:
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.
In terms of my code above, here are my specific questions:
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? If not, what is a better way of doing so?
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? 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.
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? 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?
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. So in my code example above, I hope that it clarifies 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.
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? If not, what is a better way of doing so?
As per your code sample, 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.
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? 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). So, you really don't need to use updWizHP = Player.attack(_enemy);
but you can simply use 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.
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? 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?
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)
will give you compilation error because you are not defining Player
as an object reference variable. You have to use some variable, cannot use class name like this. Better use _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.
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
That's the beauty of "Inheritance" and "Program to interface". I would recommend you to search and learn about these 2 concepts.
giveMeAnyCharacter(Character char)
can be used as giveMeAnyCharacter(new Person())
or giveMeAnyCharacter(new Enemy())
.this
means current object or instance and super
means super class. So, either create a new object or if you want to use the same object on which you are presenting working then use this
.