2016-02-29 17 views
5

Biorę tutorial na temat budowy prostego zachowania Ai. Klasa "mózgu" jest abstrakcyjna i zawiera stany takie jak "bieganie", "sukces", "porażka". Teraz w jednostce my ai - klasie droidów mam metodę uruchamiania mózgu robota.Czy można odwołać się do metody klasy abstrakcyjnej w metodzie klasy, która jej nie rozszerza?

public void update(){ 

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

    } 

Teraz nie jest to możliwe w java, ponieważ jest statycznym odwołaniem do metody niestatycznej. Rutynowe klasa abstrakcyjna, że ​​staram się odwoływać tu idzie tak:

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


} 

Próbowałem kopiowanie metodę do jednej z klas, które rozszerza rutynowych, ale to nie działa albo ten sam problem pojawia się. Wymaganie statyczne jest szczególnie trudne przy uruchomieniu() i działaniu(), które to zawierają. i są inicjatorami. Mogę tylko uczynić metodę update() taką, jaka jest, w procedurze, w której inicjalizuję droida i tablicę, na której będzie działać - ale nie widzę tego tak, jak chciałbym mieć rozwiązanie.

+1

Czy można zainicjować jedną taką klasę przez fabrykę i użyć instancji? Możesz zadeklarować ostateczną procedurę rutynową = RoutineFactory.createRoutine(); i użyj go w swoich połączeniach zgodnie z życzeniem. Będziesz potrzebował tam implementacji, aby uruchomić metody wymagane do aktualizacji konkretnych elementów instancji. Dlaczego nie możesz korzystać z dziedziczenia? –

+0

Z pewnością potrzebujesz instancji obiektu, aby wywołać metodę na niej (abstrakcyjną lub nie). – Thilo

Odpowiedz

1

Na pewno można odwoływać się do klasy abstrakcyjnej i wywoływać jej klasy abstrakcyjne, ale obiekt, do którego się odnosimy, powinien być rozszerzeniem klasy abstrakcyjnej.

Na przykład utwórz listę różnych obiektów, wszystkie rozszerzające jedną klasę abstrakcyjną.

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

Następnie można wywołać metodę abstrakcyjną.

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

(lub Java 8)

list.forEach(ExAbstract::abstractmethod); 

Ale jeśli obiekt nie został rozszerzenie abstact, i to było streszczenie sam, dałoby to błąd.

EDYCJA: W twoim przypadku, przy klasie Rutyna, powinieneś utworzyć konstruktor, a następnie utworzyć nowy obiekt. (Widzę, że masz już konstruktor ...) Jeśli chcesz użyć metody bez tworzenia obiektu, użyj static

W Routine.java:

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

W rutynowej rozmowy:

Routine r = new Routine(a); 
r.start(); 
Powiązane problemy