2012-06-20 2 views
2

Хорошо, я сначала положу код, чтобы сделать его более ясным.подклассы абстрактного класса содержат объект, который не может получить доступ к реализации абстрактного метода.

*** Редактировать: Задача решается путем передачи экземпляра последовательности в диалог при создании последовательности, тогда диалог имеет внутреннюю ссылку для вызова.

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

То, что я хочу, так это для диалога, чтобы иметь возможность вызвать метод удар() реализован в зависимости от того, класс владеет экземпляр диалога. Я использую IntelliJ IDEA, и он говорит мне, что «нестатический метод не может ссылаться на статический контекст».
Все это выполняется внутри приложения, которое создает экземпляры объектов Sequence в зависимости от контекста игры, поэтому для удара нужно будет ссылаться на нестатические объекты в последовательности.

ответ

2

Вы объект Dialog не можете знать, с какими RavelSequence он является частью. Поэтому то, что вы пытаетесь сделать, невозможно. Включите 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(); 
    } 
} 
+1

Хорошо, это работает! Кажется, это было немного легче, чем я думал. Я изменю измененный код в вопросе. Спасибо! – sideways8

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.

+0

Это не компилируется, я сказал «ravelSequence.RavelSequence» не является классом вшита. – sideways8

0

Вам нужен экземпляр реализации RavelSequence. Поскольку RavelSequence является абстрактным, он не может быть напрямую обусловлен.

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

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

Объекты BattleSequence и OutOfBattleSequence, так сказать, «запускают шоу», но им нужно знать, когда диалог получает «хит», поэтому я не думаю, что создание новой последовательности будет работать. конкретная битва-эквивалентность или аутообъект; в зависимости от того, что вызвало диалоговое окно, вызывающее удар. – sideways8

+0

, который был образцом, чтобы показать, как создать RavelSequence. конечно, это должно быть обусловлено до того, как событие будет запущено, иначе стратегия будет бесполезной. – jocelyn