user1736049
user1736049

Reputation: 366

Calling a method on object from it's class subclass

I am trying to call a method from the class Weapon, which is a subclass of Item. As you can see from the field I've declared the object currentWeapon as an object of Item, and in the setCurrentWeapon method I use getClass() method to check that the Item is really of subclass Weapon.

Is there a way that I can successfully call the methods from Weapon class on my Item object (which in reality is of Weapon class)?

backpack is an hashmap that contains Item objects. If I set currentWeapon as a Weapon in the field, the Weapon object won't be added to the backpack.

The method that fails to compile: (cannot find symbol - method getMinDamage())

public int attack(Imperial currentEnemy) {
    int damage = Utils.random(currentWeapon.getMinDamage(), currentWeapon.getMaxDamage()+1);
    currentEnemy.changeHealth(-damage);
    return damage;
}

The field:

private Item currentWeapon;

Method for setting currentWeapon:

public boolean setCurrentWeapon(String itemToEquip) {
    if(useItem(itemToEquip) == true) {
        currentWeapon = backpack.get(itemToEquip.toLowerCase());
        if(currentWeapon.getClass() == Weapon.class) {
            System.out.println(getNick() + " has equipped " + currentWeapon.getName() + " as current weapon");
            equipped = true;
            return true;
        }
        else {
            System.out.println(itemToEquip + " is not a weapon");
            currentWeapon = null;
            return false;
        }
    }
    else System.out.println(itemToEquip + " is not owned by " + getNick());
    return false;
}

I hope this question wasn't too confusing, please give tips on how to clarify if this is a problem

Upvotes: 2

Views: 184

Answers (3)

Bill the Lizard
Bill the Lizard

Reputation: 405715

You could check the type of the Item with instanceof Weapon then cast the Item to a Weapon.

A better design for your Backpack might be to make it a class that wraps different collections of different types of inventory. For example you could have:

class Backpack {
    List<Weapon> weapons;
    List<Armor> armory;
    List<Provision> provisions;
    ...
}

Then overload an add method so items are added to the right collection.

That would give you the flexibility to loop through all of the collections if you need to treat all of the items in your backpack as generic Items (for example if you need to get the total weight of your backpack), but still keep different types of Items separate for convenience.

Upvotes: 2

user1131435
user1131435

Reputation:

You can use instanceof to check whether or not something is an instance of a class. In this case, you could use:

Weapon a; Item b;
if(a instanceof Weapon) returns true
if(b instanceof Weapon) returns false

Then, you can simply cast it.

instanceof checks to see whether the object in its first argument is of the second argument's type, and can therefore be safely be cast the the type in its second argument. So, if an item is a weapon, it must be instantiated specifically as a weapon.

Therefore, Weapon instanceof Item would also be true.

The reason for the error in your code is that you're invoking a Weapon-only function on an Item; you first need to check to see if you can cast the Item to Weapon, then cast it.

Upvotes: 1

Nathaniel Waisbrot
Nathaniel Waisbrot

Reputation: 24473

Your problem is that when you call

currentWeapon.getMinDamage()

currentWeapon has type Item. It's run-time type is Weapon, but you're getting a compile-time error about it being the wrong type. If you want the field to remain of type Item, you will need to cast it to a Weapon before calling that method, to tell the compiler that you expect it to really be of type Weapon:

((Weapon)currentWeapon).getMinDamage()

Upvotes: 4

Related Questions