Kasper Grønbek
Kasper Grønbek

Reputation: 63

Polymorphism refering to childclass

I have an assignment, where I should make a mazegame. In that game I have to include polymorphism.

I want to run the method in my childclass Snake, but when I try to access it from my Game class it runs the method in the parentclass Monsters instead of the one in the childclass Snake

Since my whole code is really confusing, I will only post the code necessary, if needed for the context I can post more.

My parentclass:

package tag1;
import textio.SysTextIO;
import textio.TextIO;

public class Monsters {

    TextIO io = new TextIO(new SysTextIO());

    public void fight(){
        io.put("You have encountered a Monster, will you fight it for a 
potential reward?");   
    }

}

My childclass - The method in this class is the one i want to run

package tag1;
import java.util.ArrayList;
public class Snake extends Monsters {

public void fight(Player p, ArrayList<String>currentInventory) {


    boolean condition = true;
    String choice;
    io.put("You have encountered a resting SNAKE, will you fight it for a 
potential reward? Y/N \n");
    choice = io.get();
    while (condition) {
        switch (choice) {
            case "y":
                io.put("The snake seems to realize your intentions, it looks like it is going to bite, \n"
                        + " will you punch it or stomp on it? type P/S \n");
                choice = io.get();
                if (choice.equals("P")) {
                    io.put("You got too close, and the snake bit you! , and you lost 20 health!\n");
                    p.setHealth(p.getHealth()-20);
                    io.put("you Currently have " + p.getHealth());
                    //Alternativt kan man give personen et vigtigt ITEM senere i spillet, med et andet
                    //dyr fra Monster superklasssen
                } else if(choice.equals("S")){
                    io.put("You succesfully killed the snake, with your stomp, and discover"
                            + "a healthpotion underneath the snake!\n");
                    currentInventory.add("healtpotion");
                    io.put("Healthpotion added to inventory - to use healthpotion type HP");
                }   condition = false;
                break;
            case "n":
                io.put("you silently move around, as the snake rests \n");
                condition = false;
                break;
            default:
                io.put("Seems like you have entered something invalid, type Y / N \n");
                choice = io.get();
                break;
        }

        }
    }
}

In my game Class i have this method

public void monsterFight(Player p, ArrayList<Room> roomList){
    if (p.getCurrentRoom().equals(roomList.get(1))) {
       fightMonsters(snakeObject);
    }
}

-->

public void fightMonsters(Monsters variabel){
    variabel.fight();
}

But this goes method refers to my parentclass version of fight() instead of the childclass version?

Upvotes: 2

Views: 48

Answers (3)

Al-un
Al-un

Reputation: 3422

Methods signature

You're not calling the proper method: At the end, your Snake class has two fight method signatures:

  • public void fight() (from Monster class)
  • public void fight(Player p, ArrayList<String>currentInventory) (from Snake class)

which means that in your monsterFight(Player p, ArrayList<Room> roomList) method, you have to change to something like:

public void monsterFight(Player p, ArrayList<Room> roomList){
    if (p.getCurrentRoom().equals(roomList.get(1))) {
       // your monster has to fight a player!
       fightMonsters(snakeObject, p);

       // option B is to directly call:
       // snakeObject.fight(p, p.getInventory());
       // with the assumption on getInventory() defined later
    }
}

with also the following changes:

public void fightMonsters(Monsters variabel, Player p){
    variabel.fight(p, p.getInventory());
}

assuming that getInventory(); signature is public List<String> getInventory();. This way, your monster is calling the proper method.

Abstract class

However, this is still incorrect: in Monster class, fight(Player, List<String>) does not exist. One option is to declare your Monster as an abstract class:

public abstract class Monster{
    public void fight(){
        // your method that you define
    }

    // this method has to be overridden in children classes
    public abstract void fight(Player p, List<String> inventory);
}

Consequently, your Snake class will look like:

public class Snake extends Monster{

    @Override
    public void fight(Player p, List<String> inventory){
        // your method
    }

}

Then, you can call a fight method for any monster.

Upvotes: 2

Pleasant94
Pleasant94

Reputation: 511

Polymorphism in Java is the ability of an object to have different forms, for example for a class to call different methods.

The compiler can choose between the two fight methods because they are different, based upon the number (and types) of arguments passed.

Snake.fight(Player, ArrayList<String>) has 2 parameters, and Monster.fight() has 0 parameter.

Upvotes: 1

Neo
Neo

Reputation: 3786

Method overloading works only if the overloaded and overloading methods have the same signature, meaning the same parameter types and same return type.

The method in Snake has two arguments, while the method in Monsters has no parameters at all, so it is not overloaded.

When you call Snake.fight(), such a method is searched for but not found (no method is called fight() and accepts zero arguments), so the parent method is called.

Bonus:
The Monsters class looks like a simple parent class for all the monster types such as snake, skeleton, goblin or whatever, which should never be instantiated. In such case it's probably better to make it abstract, with no method implementations at all, so you won't invoke it's methods by mistake.

Upvotes: 3

Related Questions