2016-03-19 18 views
-1

Ich bin ein wenig neu in Java, und ich versuche, ein RPG der Art zu schreiben.Abstrakte Methoden ohne abstrakte Klassen

Jetzt im Spiel der Spieler Charakter Fähigkeiten haben würde. Diese könnten sehr unterschiedlich sein, von verletzenden Feinden über die Heilung des Spielers bis hin zu vielen anderen Dingen. Es wäre sinnvoll, eine Skill-Klasse mit einer abstrakten applyEffect() -Methode zu erstellen, die für jede bestimmte Fertigkeit definiert wird.

Allerdings kann ich keine abstrakte Klasse mit abstrakten Methoden haben, und jede Fähigkeit sollte ein Objekt der Fähigkeitsklasse sein, also kann sie nicht abstrakt sein. Die offensichtliche Lösung besteht darin, die Skill-Klasse abstrakt zu machen und eine Unterklasse für jede einzelne Fertigkeit zu erstellen, und dann instanziieren, dass in ein Objekt zu verwenden. Dieser Ansatz scheint ein wenig überflüssig. Gibt es sonst noch etwas, was ich in dieser Situation möglicherweise tun könnte?

EDIT: Wenn ich schon dabei bin, wenn ich ein Objekt möchte, das ein einziges Mal mit Standardvariablen angezeigt wird, gibt es eine Möglichkeit, eine Klasse nur für dieses eine Objekt zu erstellen und dann zu instanziieren?

+1

Abstrakte Methoden müssen in einer Unterklasse implementiert werden. Ohne Unterklassen, wie werden Sie sie implementieren? – immibis

+0

Sie benötigen eine abstrakte Skill-Klasse. Jeder Skill- oder Skill-Typ oder was auch immer kann die Skill-Klasse erweitern und eine konkrete applyEffect() -Methode enthalten. – lhoworko

+0

Sie haben Recht, aber ich möchte wissen, ob es einen Workaround gibt. Es scheint überflüssig zu sein, beispielsweise eine DamageSkill1-Unterklasse zu erstellen und dann in einem DamageSkill1-Objekt zu instanziieren, da letzteres nur in einer Instanz erscheint. Es schlägt den Zweck der Klasse. – Sotos

Antwort

0

Ich würde keine Fähigkeiten (wie 'heilen' und 'verstecken') als Klassen schreiben. Ich betrachte Klassen als Objekte (Spieler) und Methoden als Fähigkeiten (Fähigkeiten). Fähigkeiten wie 'heilen' oder 'verstecken' sind eindeutig besser als Methoden als Klassen.

Ich hätte einfach eine Klasse, die alle Methoden hat, aber nur die ausgewählten sind für den Einsatz verfügbar. Die Fähigkeiten als Enums zu haben, ist auch keine schlechte Idee.

Jetzt können die Spieler eingeschränkt werden, nur die Methoden zu verwenden, die ihnen zur Verfügung stehen sollten. Ich würde wahrscheinlich eine GameHandler-Klasse schreiben, um sich um alles zu kümmern und dort alles zu überprüfen.

+0

Ein interessanter Ansatz. Wahrscheinlich besser als meiner. Was ich befürchte ist, dass, wenn die Fähigkeiten mindestens 100 (verteilt auf mehrere Spieler-Proffessions) erreichen, diese eine Spieler-Klasse humongous und unhandlich werden würde, wie alle canUseSkill booleans. Andererseits könnte ich das alles in einer anderen Klasse ablegen, wie Sie sagen. Ich denke, Ihr Ansatz ist der logischste, danke^_^ – Sotos

+0

@Sotos Sie könnten auch Schnittstellen verwenden, wenn es zu kompliziert wird. – Gendarme

0

Wie wäre es damit:

public abstract class Skill { 
    public abstract void applyEffect(); 
} 


... somewhere else ... 
Skill dig = new Skill() { 
    @Override 
    public void applyEffect() { 
     doSomeDigging(); 
    } 
}; 

Dieses nach wie vor eine Unterklasse im Hintergrund erstellt, aber Sie könnten es besser gefällt.

+0

Dies ist eine anonyme Klasse, oder? Es scheint der schärfste Weg zu sein, aber ich denke, sie sind nur lokal. Das wäre ein großes Hindernis, da ich sie in Klassen und Paketen weitergeben muss. – Sotos

+0

Sie können die Instanz weitergeben, da sie der Skill-Klasse entspricht. Aber vielleicht möchten Sie Ihre Anforderungen in der Frage klären. – sfThomas

0

ich würde enums auch verwenden, Sie können eine Reihe von Login in ihnen stopfen. Die Karten lassen jeden Spieler die Fähigkeiten und Werte haben, die er braucht. Sie können Enums wie this oder that verschachteln.

import java.util.Map; 
import java.util.Random; 
import java.util.TreeMap; 
public class So36107587 { 
    enum Stat { 
     food,health,magic; 
    } 
    enum Skill { 
     heal,hurt,hunt; 
     static void apply(Skill skill,double amount,Player player) { 
      double a=amount*random.nextDouble(),x; 
      switch(skill) { 
       case heal: 
        x=player.stats.get(Stat.health); 
        player.stats.put(Stat.health,a+x); 
        break; 
       case hurt: 
        x=player.stats.get(Stat.health); 
        player.stats.put(Stat.health,a-x); 
        break; 
       case hunt: 
        x=player.stats.get(Stat.food); 
        player.stats.put(Stat.food,a+x); 
        break; 
      } 
     } 
     static final Random random=new Random(); 
    } 
    static class Player { 
     Player() { 
      init(); 
     } 
     void init() { 
      for(Stat stat:Stat.values()) 
       stats.put(stat,1.); 
      for(Skill skill:Skill.values()) 
       skills.put(skill,1.); 
     } 
     void apply(Skill skill,Player player) { 
      Skill.apply(skill,skills.get(skill),player); 
     } 
     @Override public String toString() { 
      return ""+skills+" "+stats; 
     } 
     final Map<Stat,Double> stats=new TreeMap<>(); 
     final Map<Skill,Double> skills=new TreeMap<>(); 
    } 
    public static void main(String[] args) { 
     Player player=new Player(); 
     System.out.println(player); 
     player.apply(Skill.heal,player); 
     System.out.println(player); 
     player.apply(Skill.hunt,player); 
     System.out.println(player); 
    } 
} 
Verwandte Themen