抽象类的子类包含一个无法访问抽象方法实现的对象

时间:2012-06-20 13:17:53

标签: java inheritance object subclass abstract

好的,我会先把代码放在首位,以便更清楚。

***编辑: 通过在创建序列时将序列的实例传递给对话框来解决问题,然后对话框具有要调用的内部引用。

public abstract class RavelSequence {
    protected Dialog dialog; //every subclass uses one of these objects
    public abstract void hit();
}

public class BattleSequence extends RavelSequence {
    public void init(){                //this is the edited fix
        dialog.setSequence(this);      //
    }                                  //

    public void hit(){ //the effect of a 'hit' in battle
        doSomething();
    } 
}

public class OutOfBattleSequence extends RavelSequence {
    public void init(){                //this is the edited fix
        dialog.setSequence(this);      //
    }                                  //

    public void hit(){ //the effect of a 'hit' outside battle
        doSomethingElse();
    }
}

public class Dialog extends Container implements Runnable {
    private RavelSequence sequence;                  //this is the edited fix
    public void run (){
        if (somethingHappens)
            sequence.hit();
    }
    public void setSequence (RavelSeqence sequence){ //this is the edited fix
        this.sequence = sequence;                    //
    }                                                //
}

我想要发生的是Dialog能够调用在拥有Dialog实例的任何类中实现的方法hit()。我正在使用IntelliJ IDEA,它告诉我'非静态方法命中不能从静态上下文引用。'
整个过程在一个应用程序中运行,该应用程序根据游戏的上下文创建Sequence对象的实例,因此命中将需要引用Sequence中的非静态对象。

3 个答案:

答案 0 :(得分:2)

由于hit()不是静态方法,因此您需要访问RavelSequence的封闭实例才能调用它。

如果this是嵌套类,则使用Dialog关键字执行此操作:

public abstract class RavelSequence {
    public class Dialog extends Container implements Runnable {
        public void run (){
            RavelSequence.this.hit();
        }
    }
    public abstract void hit();
}

否则,您需要将RavelSequence的实例传递到Dialog实例。

答案 1 :(得分:2)

你的Dialog对象无法知道它是哪一个RavelSequence。所以你要做的就是这样做不可能。在Dialog中包含一个RavelSequence,它可以正常工作。

例如:

public class Dialog extends Container implements Runnable {
    protected RavelSequence sequence;

    public Dialog(RavelSequence sequence) {
        this.sequence = sequence; // or any other mean to set your RavelSequence: setter, dependency injection...
    }

    public void run (){
        if (somethingHappens)
            sequence.hit();
    }
}

答案 2 :(得分:0)

您需要一个RavelSequence实现的实例。因为RavelSequence是抽象的,所以不能直接实例化。

public class Dialog extends Container implements Runnable {
    public void run (){

        if (somethingHappens)
            RavelSequence  ravel = new OutOfBattleSequence(); // we choose implementation
            ravel.hit();
    }
}