Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is it possible to make a reference to an abstract class method in a class method that doesn't extend it?

I'm taking a tutorial on building a simple behavior Ai. It's 'brain' class is abstract and contains states as in "running","success","failure". Now in the my ai unit - droid class i have a method to start the brain of the droid up.

    public void update(){

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

    }

Now this isn't possible in java because it's a static reference to a non-static method. The routine abstract class that i'm trying to reference to here goes like this :

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


}

I've tried copying the method to one of the classes that extends the Routine, but that doesn't work either the same problem comes up. The static requirement is especially difficult on start() and act() that contain this. and are initializers. I can only make the method update() like it is, in the routine where i initialize the droid and the board it will be acting on - but i don't see this quite like the solution i'd like to have.

like image 826
Faris Kapo Avatar asked Nov 08 '22 19:11

Faris Kapo


1 Answers

For sure, you can reference an abstract class and call its abstract classes, but the object you exactly reference should be an extender of the abstract class.

For example, create a list of different objects, all extending one abstract class.

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

And then, you can call abstract method on it.

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

(Or Java 8)

list.forEach(ExAbstract::abstractmethod);

But if object wasn't extending abstact, and it was abstract itself, it would give an error.

EDIT: In your case, with Routine class, you should make a constructor for it, and then make a new object. (I see you have a constructor already...) If you want to use a method without creating an object, use static

In Routine.java:

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

In your Routine call:

Routine r = new Routine(a);
r.start();
like image 95
Kirill Semyonkin Avatar answered Nov 14 '22 21:11

Kirill Semyonkin