2012-02-09 14 views
5

私は知っていますが、これを回避するためのほとんどのケースをカバーする単純な答えがあります。条件式に応じてJavaの `if`ステートメント内で変数が宣言されています。

私の場合、ユーザー入力情報を使用してゲームでCPUプレーヤーを作成したいと考えています。ユーザーが簡易モードを選択した場合は、EasyPlayerクラスのインスタンスを宣言してインスタンス化します。それ以外の場合は、HardPlayerクラスのインスタンスを宣言してインスタンス化します。いずれにせよ、変数の具体的な名前は "cpu"でなければならず、残りのコードは無差別に "cpu"で動作します。つまり、これらがどのように動作するかの相違点は、異なるクラスに組み込まれており、CpuPlayerクラスをサブクラス化しています。

// Set the opponent. 
if (difficulty == 0){ 
    EasyPlayer cpu = new EasyPlayer(num_rounds); 
} 
else{ 
    HardPlayer cpu = new HardPlayer(num_rounds); 
} 

これは私に絶えず迷惑cannot find symbolエラーを与える:

は、だからここのコードです。私が読むことから、スコープの問題とそれが決して起こらない可能性のために、このような条件の中で宣言を行うことはできないという皆が言います。

もしそうなら、ユーザー入力に基づいて2つの異なるクラスの1つとして1つの変数を代わりに宣言する正しい方法は何ですか?

+1

+1あなたがここにいる解決策が不十分であり、助けに来ていることを認識してください。 –

答えて

10
CpuPlayer cpu; 

if (difficulty == 0){ 
    cpu = new EasyPlayer(num_rounds); 
} 
else{ 
    cpu = new HardPlayer(num_rounds); 
} 
+0

ああ。頭が激しい瞬間ありがとうございました。 – ely

0

最初に宣言してから割り当てます。

// Set the opponent. 
CpuPlayer cpu = null; 
if (difficulty == 0){ 
    cpu = new EasyPlayer(num_rounds); 
} 
else{ 
    cpu = new HardPlayer(num_rounds); 
} 
if(cpu == null) throw new IllegalStateException(); 
+0

IFへのELSEがあるので、最初のnull割り当ては不要です。 HardPlayerがCpuPlayerから継承し、HardPlayerが構築中に例外をスローしない限り、プログラムの最初と最後の行は不要なようです。何か不足していますか? – eternaln00b

+0

@SiddharthaShankarこれは習慣です。しばしば、この変数は割り当てられていない可能性があります。 – corsiKa

+2

nullの割り当てとそれに続くチェックは、不必要ではないだけでなく、コンパイル時のチェックをランタイムチェックに変えるという点で有害です。最初の代入がなければ、 'else'節の後に' cpu'を使用しようとすると、 'cpu'に値が割り当てられていなければコンパイル時エラーが発生します(この場合、2つの' new'インスタンスのうちの1つ)コードブランチ。言い換えれば、値を設定することを忘れたコードブランチがあった場合、コンパイラは(ランタイム例外をスローするのではなく)あなたに伝えます。 – yshavit

0
// Set the opponent. 
CpuPlayer cpu; 
if (difficulty == 0){ 
    cpu = new EasyPlayer(num_rounds); 
} else{ 
    cpu = new HardPlayer(num_rounds); 
} 
1
CpuPlayer cpu; 
// Set the opponent. 
if (difficulty == 0){ 
    cpu = new EasyPlayer(num_rounds); 
} else{ 
    cpu = new HardPlayer(num_rounds); 
} 
2

あなたの意図がCpuPlayerクラスに使用可能な唯一のメソッドを呼び出すことであれば、おそらく使用するより良いデザインパターンは、Strategy Patternです。あなたのケースでは、あなたはおそらくCpuStrategyと呼ばれる新しいクラスを追加して、のようなものにあなたのCpuPlayerコンストラクタを変更します。これは、あなたのコードの残りの部分読みやすく、あまりにも維持するために、おそらく簡単になり

public CpuPlayer(CpuStrategy strategy, int num_rounds) 

。 CpuStrategyクラスは難易度の違いを処理するため、私たちは、もし/他を処分した

CpuPlayer cpu = new CpuPlayer(new CpuStrategy(difficulty), num_rounds); 

:ここでは、コードの元のスニペットは、次のようになります。これはまた、プログラムの肉から難易度の概念を抽象化することができるので意味があります。これはゲームの演奏部分であると想定しています。

+0

チップと追加の詳細をありがとう。これは確かに良い再設計のアイデアです。 – ely

0

クラス構造の設計を調整することができます。 Levelという名前の親クラスを作成し、EasyLevelおよびHardLevelという名前の2つの子クラスを拡張します。

class EasyLevel : public Level 
{ 

    //implementation specific to easy level 
} 

class HardLevel : public Level 
{ 
    //implementation specific to hard level 
} 

プレーヤークラスでは、コンストラクタを変更してLevel型のパラメータを取得します。

class Player 
{ 
    Level level; 
    int rounds; 

    public: 
    Player (Level level, int num_rounds) 
    { 
     this.level = level; 
     this.rounds = num_rounds; 
    } 

    play() 
    { 
     // use level variable to invoke implementation specific to the set level, hard or easy. 
    } 
} 

これにより、クラス構造がより拡張可能になります。たとえば、別のレベルの「ミディアム」を将来追加する必要がある場合、親クラスのレベルから拡張する必要があります。

関連する問題