2016-02-29 13 views
5

Ich nehme ein Tutorial zum Erstellen eines einfachen Verhaltens Ai. Es ist "Gehirn" -Klasse ist abstrakt und enthält Zustände wie "Laufen", "Erfolg", "Versagen". Jetzt in der My Ai Unit - Droid Klasse habe ich eine Methode, um das Gehirn des Droiden zu starten.Ist es möglich, eine abstrakte Klassenmethode in einer Klassenmethode zu verwenden, die sie nicht erweitert?

Nun ist dies in Java nicht möglich, da es sich um eine statische Referenz auf eine nicht statische Methode handelt. Die Routine abstrakte Klasse, die ich versuche, hier zu verweisen geht so:

public abstract class Routine { 

    public enum RoutineState{ 
     Success, 
     Failure, 
     Running 
    } 

    protected RoutineState state; 

    protected Routine() { } 

    public void start(){ 
     this.state = RoutineState.Running; 
    } 

    public abstract void reset(); 

    public abstract void act(droid droid, board board); 

    public void succed(){ 
     this.state = RoutineState.Success; 
    } 

    public void Fail(){ 
     this.state = RoutineState.Failure; 
    } 

    public boolean isSuccess(){ 
     return state.equals(RoutineState.Success); 
    } 

    public boolean isFailure(){ 
     return state.equals(RoutineState.Failure); 
    } 

    public boolean isRunning(){ 
     return state.equals(RoutineState.Running); 
    } 

    public RoutineState getState(){ 
     return state; 
    } 


} 

Ich habe versucht, die Methode zu einer der Klassen zu kopieren, die die Routine erstreckt, aber das funktioniert auch nicht die Das gleiche Problem kommt auf. Die statische Anforderung ist besonders schwierig bei start() und act(), die dies enthalten. und sind Initialisierer. Ich kann nur die Methode update() wie es ist, in der Routine, wo ich den Droiden und das Board initiieren wird es auf - aber ich sehe das nicht ganz so wie die Lösung, die ich gerne haben würde.

+1

Ist es möglich, eine solche Klasse von einer Fabrik zu initialisieren und die Instanz zu verwenden? Sie können die letzte Routine routine = RoutineFactory.createRoutine(); und benutze es bei deinen Anrufen wie gewünscht. Sie werden dort eine Implementierung benötigen, um die Methoden auszuführen, die Sie benötigen, um instanzspezifische Elemente zu aktualisieren. Warum können Sie keine Vererbung verwenden? –

+0

Sie benötigen sicherlich eine Objektinstanz, um eine Methode aufzurufen (abstrakt oder nicht). – Thilo

Antwort

1

Sicher können Sie eine abstrakte Klasse referenzieren und ihre abstrakten Klassen aufrufen, aber das Objekt, auf das Sie genau verweisen, sollte ein Extender der abstrakten Klasse sein.

Zum Beispiel, erstellen Sie eine Liste von verschiedenen Objekten, die alle eine abstrakte Klasse erweitern.

public abstract class ExAbstract { public abstract void abstractmethod() {...} } 
public class ExampleA extends ExAbstract { @Override... } 
public class ExampleB extends ExAbstract { @Override... } 
... 

List<ExAbstract> list = new ArrayList<>(); 
list.add(new ExampleA()); 
list.add(new ExampleB()); 
... 

Und dann können Sie abstrakte Methode darauf aufrufen.

for (ExAbstract test : list){ 
    test.abstractmethod(); 
} 

(Oder Java 8)

list.forEach(ExAbstract::abstractmethod); 

Aber wenn das Objekt nicht abstact erstreckt, und es war abstrakt selbst, würde es einen Fehler geben.

EDIT: In Ihrem Fall, mit Routine-Klasse, sollten Sie einen Konstruktor dafür machen, und dann ein neues Objekt erstellen. (Ich sehe, Sie haben einen Konstruktor bereits ...) Wenn Sie eine Methode verwenden möchten, ohne ein Objekt zu erstellen, verwenden static

In Routine.java:

public Routine(ExampleArg a){ 
    this.a = a; 
} 

in Ihrer Routine Aufruf:

Routine r = new Routine(a); 
r.start(); 
Verwandte Themen