0

私のプログラムには次のクラスがあります。

public abstract class Question {

    private Topic topic;
    private String text;

    // methods

}

public class OpenQuestion extends Question {

    // methods

}

public class MultipleChoiceQuestion extends Question {

    private List<String> options = new ArrayList<String>();
    private String correct;

    // methods

}

また、私が持っている別のクラス Test があります:

Question question;

// if the question is open

    if(question instanceof OpenQuestion) {

    ...

    }

// if the question is multiple choice

    if(question instanceof MultipleChoiceQuestion) {

    ...

    }

instanceofOOPの原則に違反していると言われたので、私はに代わるものを見つけようとしています。

質問がオープンか多肢選択かを知るための他の良い方法はありますか?

4

4 に答える 4

4

キーワード自体は OOPのinstanceof原則を破るものではありません。おそらく、ポリモーフィズムを使用してロジックを実行する必要があることを意味していました。

それ以外の:

if(question instanceof OpenQuestion) {

...
}

//Countless ifs

if(question instanceof MultipleChoiceQuestion) {
...

}

あなたがすべき

question.doAction();

別の例 (より明示的):

abstract class Animal{
    public abstract void speak();
}

class Dog extends Animal{
    public void speak(){ System.out.println("Bark!"); }
}

class Cat extends Animal{
    public void speak(){ System.out.println("Meow!"); }
}
于 2013-05-15T00:05:24.870 に答える
0

もちろん、この例を見ることができます:

import java.lang.reflect.*;
import java.awt.*;

class SampleName {

public static void main(String[] args) {
Button b = new Button();
printName(b);
}

static void printName(Object o) {
   Class c = o.getClass();
   String s = c.getName();
   System.out.println(s);
}
}
于 2013-05-15T00:04:08.787 に答える
0

OOPを壊すのはinstanceof自体ではなく、あなたのクラスがそれを壊すインスタンスである特定のクラスを知っています。

あなたのクラスが犬、猫、または鳥の「動物」である場合... Animal.legs() は、動物の種類を知らなくても足を数えるのに十分なはずです-これはもちろん簡単なケースです。より困難なケースは、一部の動物が他の動物にとって意味をなさない方法を持っている場合です。

犬や猫には当てはまらない fly() の場合を考えてみましょう。この場合、いくつかの解決策がありますが、奇妙なことに、instanceof が最適な場合があります。

できること: fly() を bird にのみ実装し、反映して、bird に fly() メソッドがあるかどうかを確認します。すべてのクラスに canFly() と fly() を実装し、fly() ができない場合は例外をスローします。

これらはどちらも良いものではありません.OOではありません.理由もなく醜くて繰り返しです.

それで、良い解決策は何ですか?fly() メソッドを宣言する「Flies」インターフェースを持ち、「Bird」のみが Flies を実装します。この場合、instanceof は非常に優れたソリューションです。おそらく最高です!

悪い例: if(animal instancef Bird) ((Bird)animal).fly()

良い: if(ハエの動物インスタンス) ((ハエ)動物).fly()

その理由がわかるまでは、かなり微妙な違いです。Bat を追加するとどうなるでしょうか。あなたが持っている最初のもので:

if(animal instancef Bird)
    ((Bird)animal).fly()
else if(animal instancef Bat)
    ((Bat)animal).fly()

これはスイッチ、コンストラクトであり、OO 言語でスイッチ コンストラクトをコーディングしていることに気付くときはいつでも、おそらく何か間違ったことをしている可能性があります (これが、switch コンストラクトにつながるため、instanceof が間違っていると彼らが言う理由です)。

2 番目の例は、Bat が Flies を実装している限り変更されずに機能し、実装した新しいオブジェクトに対しても引き続き機能します。これはすごさです。

このようにインターフェイスを使用すると、ダック タイピングやリフレクションよりも有利になります。具体的で意図的なものだからです。うっかり Pants オブジェクトに対して .fly() を呼び出して、予期しない Zipper を返すことはなく、「bat」のコードを調べて意図を簡単に理解できます。

于 2013-05-15T00:32:32.637 に答える