1

I have following classes structure extention: Entity > Creature > (abstract)Player > Mage. In Mage class I implement interface iCastable with method castSpell(). In main method I create new Mage(...).

Problem is that when I send it as a prop of Player class someMethod(Player player), I cannot use methods implemented from interface iCastable. I can only use methods from Creature class via player.getCreaure.whaterver() because Player extend it. How can I solve that issue?

I do not want to send it as a prop of Mage class, because I want to use all my other classes like Warrior for example. I also want to avoid player instanceof Mage, because if I had 1000 classes I must do 1000 check for every method. Do you have any ideas how to solve that?

EDIT added code

public class Creature extends Entity {...}

public abstract class Player extends Creature {
    public Player(String name) {
        super(name);
    }
    public abstract void attack();
}
public class Mage extends Player implements iCastable {
    ...
    @Override
    public void castSpecial() {...}
}

public static void main(String[] args) {
   Mage mage = new Mage("Mage");
   Duel duel = new Duel(mage, monsters);
}
public class Duel {
    private Player player;
    ...
    public Duel(Player player, ArrayList<Monster> monsters) {
        this.player = player;
        ...
    }
    private void castSpecial() {
        // error here
        player.castSpecial();
    }
}

I am trying to do something like player.getInstanceClass(mage, warrior or whatever).cashSpecial()

13
  • 1
    Why do you extend the interface iCastable rather than implementing it Commented Dec 10, 2017 at 12:20
  • Typing mistake sorry Commented Dec 10, 2017 at 12:20
  • It would help if we could see code, us programmer are better at reading code than English :) Commented Dec 10, 2017 at 12:22
  • on what class/interface is the someMethod(Player player) defined ? Commented Dec 10, 2017 at 12:24
  • I suspect we need to understand more about the intended structure and functionality here. Based on the description alone... If the method expects a Player then the method's internal functionality shouldn't care what kind of Player. If the method's internal functionality is specific to a Mage then it should expect a Mage. What exactly does someMethod() do? If you were to give it a meaningful and descriptive name, what would it be? Commented Dec 10, 2017 at 12:24

1 Answer 1

4

Your method can be written like this:

private void castSpecial() {
    if (player instanceof iCastable) {
        ((iCastable) player).castSpecial();
    }
}

The instanceof performs a runtime check to see if the Player instance has the correct subclass. If the check succeeds then the type cast will also succeed. (If you do the type cast without a "guard", then it will throw an ClassCastException if the player doesn't have the required type.)

Obviously, if the player does not have spell casting ability, the method does nothing.


Note: the interface name iCastable is wrong from two perspectives.

  1. A class or interface name should never start with a lowercase letter.

  2. The name is wrong. ICastable implies that you would "cast" a Mage. In fact, the Mage is the subject, that casts the spell, not the spell that is cast. A better name might be ISpellCaster.

Sign up to request clarification or add additional context in comments.

2 Comments

This is the answer I am looking for
Bear in mind that if you're doing a lot of instanceof checks and downcasts it can be a code smell. It seems like this use-case might be better solved using composition rather than inheritance. For example each creature could contain an array of IAbility and casting a spell could be a type of ability, used by calling IAbility.activate() for example, without any need to downcast.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.