Reputation: 103
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
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
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