2016-02-29 37 views
5

Sto seguendo un tutorial sulla creazione di un comportamento semplice Ai. La sua classe "cerebrale" è astratta e contiene stati come "in esecuzione", "successo", "fallimento". Ora nella mia unità ai - classe droide ho un metodo per avviare il cervello del droide.È possibile creare un riferimento a un metodo di classe astratta in un metodo di classe che non lo estende?

public void update(){ 

     if(Routine.getState()==null){ 
      Routine.start(); 
     } 
     Routine.act(this, board); 

    } 

Ora questo non è possibile in java perché è un riferimento statico a un metodo non statico. La classe astratta routine che sto cercando di fare riferimento a qui va in questo modo:

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; 
    } 


} 

Ho provato a copiare il metodo per una delle classi che si estende la routine, ma che non funziona neanche il lo stesso problema si presenta. Il requisito statico è particolarmente difficile su start() e act() che contengono questo. e sono inizializzatori. Posso solo rendere il metodo update() come lo è, nella routine in cui inizializzo il droide e la scheda su cui agirà, ma non la vedo come la soluzione che mi piacerebbe avere.

+1

È possibile utilizzare per inizializzare una classe di questo tipo da una fabbrica e utilizzare l'istanza? È possibile dichiarare la routine di routine finale = RoutineFactory.createRoutine(); e usalo nelle tue chiamate come desideri. ci sarà bisogno di un'implementazione in là per eseguire i metodi necessari per aggiornare gli elementi specifici dell'istanza. Perché non puoi usare l'ereditarietà? –

+0

Hai certamente bisogno di un'istanza dell'oggetto per richiamare un metodo (astratto o non). – Thilo

risposta

1

Sicuramente, è possibile fare riferimento a una classe astratta e chiamarne le classi astratte, ma l'oggetto che si fa esattamente riferimento dovrebbe essere un estensore della classe astratta.

Ad esempio, creare un elenco di oggetti diversi, tutti estendendo una classe astratta.

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()); 
... 

E quindi, è possibile chiamare il metodo astratto su di esso.

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

(o Java 8)

list.forEach(ExAbstract::abstractmethod); 

Ma se oggetto non stava estendendo abstact, ed era per sé astratto, darebbe un errore.

MODIFICA: nel tuo caso, con la classe Routine, dovresti creare un costruttore per questo, e quindi creare un nuovo oggetto. (Vedo che hai un costruttore già ...) Se si desidera utilizzare un metodo senza creare un oggetto, utilizzare static

In Routine.java:

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

nella chiamata di routine:

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