2017-12-10 33 views
1

Ich habe folgende Klassen Struktur extention: Entity>Creature> (Auszug) Player>Mage. In Mage Klasse I implementieren Schnittstelle iCastable mit Methode castSpell(). In der Hauptmethode erstelle ich new Mage(...).Java OOP Instanz der Klasse

Problem ist, dass, wenn ich es als eine Stütze der Player-Klasse someMethod(Player player) senden, kann ich keine Methoden aus der Schnittstelle iCastable implementiert verwenden. Ich kann nur Methoden von Creature Klasse über player.getCreaure.whaterver() verwenden, weil Player es erweitern. Wie kann ich dieses Problem lösen?

Ich möchte es nicht als eine Prop von Mage Klasse senden, weil ich alle meine anderen Klassen wie Warrior zum Beispiel verwenden möchte. Ich möchte auch vermeiden, player instanceof Mage, denn wenn ich 1000 Klassen hatte, muss ich 1000 für jede Methode überprüfen. Haben Sie Ideen, wie Sie das lösen können?

EDIT hinzugefügt 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(); 
    } 
} 

Ich versuche, so etwas wie player.getInstanceClass (Magier, Krieger oder was auch immer) .cashSpecial()

+1

Warum Sie die Schnittstelle erweitern 'iCastable' anstatt deren Umsetzung –

+0

Typing Fehler leider – TeodorKolev

+0

Es würde helfen, wenn wir Code sehen können, uns Programmierer sind besser auf die Code-Lese als Englisch :) –

Antwort

4

Ihre Methode wie folgt geschrieben werden kann, zu tun:

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

Die instanceof führt eine Laufzeitprüfung durch, um festzustellen, ob die Player Instanz hat die richtige Unterklasse. Wenn der Check erfolgreich ist, ist der Typcast ebenfalls erfolgreich. (Wenn Sie den Typcast ohne "Wächter" ausführen, wird eine ClassCastException ausgelöst, wenn der Player nicht über den erforderlichen Typ verfügt.)

Offensichtlich hat die Methode player keine Fähigkeit zum Zaubern von Zaubersprüchen nichts.


Hinweis: Die Schnittstelle Name iCastable ist falsch aus zwei Perspektiven.

  1. Eine Klasse oder Schnittstelle Name sollte nie mit einem Kleinbuchstaben beginnen.

  2. Der Name ist falsch. ICastable bedeutet, dass Sie eine Mage "werfen" würden. In der Tat ist die Mage das Subjekt, das den Zauberspruch, nicht den Zauberspruch, der gegossen wird. Ein besserer Name könnte ISpellCaster sein.

+0

Dies ist die Antwort, die ich suche – TeodorKolev

+0

Beide Noten auch ausgenommen. Sie sind großartig, danke – TeodorKolev

+0

Denken Sie daran, dass wenn Sie viele instanceof Schecks und downcasts tun, es ein Code-Geruch sein kann. Es scheint so, als ob dieser Anwendungsfall besser mit Komposition statt Vererbung gelöst werden könnte. Zum Beispiel könnte jede Kreatur ein Array von Fähigkeiten enthalten, und ein Zauberspruch könnte eine Art von Fähigkeit sein, die zum Beispiel durch Aufruf von IAbility.activate() verwendet wird, ohne dass ein Downcast erforderlich ist. –