John Smith
John Smith

Reputation: 103

How to cast a subclass to a superclass [cannot convert]?

I have a general class called Hero and three subclasses that extends it: Mage, Warrior, Ranger. The Hero class has health and strength and each subclass has additional attributes.

public class Warrior extends Hero {
private int armor;

public Warrior(int health, int strength, int armor) {
    super(health,strength);
    this.armor = armor;
}

}


public class Hero {
private int health;
private int strength;

public Hero(int health, int strength) {
    this.health = health;
    this.strength = strength;

}

//Getters
public int getHealth() {
    return health;
}
public int strength() {
    return strength;
}
//Setters
public void takeDamage(Hero player, int n) {
    player.health = player.health-n;
}
public void healDamage(Hero player, int n) {
    player.health = player.health+n;
}

}

And in the main class I am trying to make two hero objects and when the user selects what class they want to be I want to create that hero class and cast it as a hero so it will have hero attributes and methods as well.

public static void main(String[] args) {

    Hero hero1 = new Hero(100,10);
    Hero hero2 = new Hero(100,10);
    //Players select the class
    Scanner scanner = new Scanner(System.in);
    System.out.println("Player select a class: Warrior, Mage, Ranger ");
    String p = scanner.next();
    switch (p) {
    case "Warrior": Warrior h1 = (Hero)hero1; //this doesn't work
        break;
    case "Mage":
        break;
    case "Ranger":
        break;
    }




}

I have looked around and I kind of understand in an example how an object may be an integer and you can do "int i = (Integer) object;". So I am confused as why my warrior who is a hero cannot be casted to a hero object.

Upvotes: 2

Views: 3753

Answers (2)

leeyuiwah
leeyuiwah

Reputation: 7152

I believe what you said below is a misconception:

... I want to create that hero class and cast it as a hero so it will have hero attributes and methods as well.

Sub-classes always have properties of their super-class. So in this case, if Warrior is a sub-class of Hero, then Warrior will have all properties and methods that Hero has, so you don't really need to "cast a sub-class to a super-class". There is never such a need.

In this particular example, what you may want to write is either this

Hero hero1 = new Hero(100 /* health */,10 /* strength */);
. . .
case "Warrior": 
    Hero h1 = hero1; 
    break;

Or this

Hero warrior1 = new Warrior(100 /* health */
                            ,10 /* strength */
                            ,20 /* armor */);
. . .
case "Warrior": 
    Hero h1 = warrior1 ; 
    break;

Or even this

Warrior warrior1 = new Warrior(100 /* health */
                               ,10 /* strength */
                               ,20 /* armor */);
. . .
case "Warrior": 
    Hero h1 = warrior1 ; 
    break;

Which one is more appropriate? It depends on your exact situation (i.e. do you really want the object to be a Hero or a Warrior).

Upvotes: 0

Christopher Schneider
Christopher Schneider

Reputation: 3915

Here:

Hero hero1 = new Hero(100,10);

You are saying that hero1 is a Hero

Here:

Warrior h1 = (Hero)hero1

you are trying to say hero1 is a Warrior, but it's not. It's a Hero.

The following is key: All Warrior instances are Hero instances, but not all Hero instances are a Warrior.

In order to cast hero1 to a Warrior, it must be created as a Warrior. e.g.

Hero hero1 = new Warrior(100,10);

Upvotes: 1

Related Questions