1

重複の可能性:
ここでの instanceof チェックに何か問題がありますか?

私はこのコードを持っています

public static int getNumberOfOwned(Player owner, String type){
    int count = 0;      
    for (Field f: board.fieldList)
        if (type == "Shipping" && f instanceof Shipping) 
            if (((Shipping)f).getOwnedBy() == owner)
                count++;
        else if (type == "Brewery" && f instanceof Brewery) 
            if (((Brewery)f).getOwnedBy() == owner)
                count++;
    return count;
}

これは非常にエレガントで将来性があるとは思いません。これらの instanceof 演算子を回避するにはどうすればよいですか。

4

8 に答える 8

2

いつでも列挙型を使用できField、型を返すメソッドを使用できます。ここでもう少し進んで、特定のタイプのカウントを更新したくないと推測します。そのため、列挙型も次のことを表すブール値で「装飾」されています。

enum FieldType {
    SHIPPING(true),
    BREWERY(true),
    NOTME(false);

    private final boolean countUpdate;

    FieldType(boolean countUpdate) { this.countUpdate = countUpdate; }
    public boolean mustUpdateCount() { return countUpdate; }
};

abstract class Field {
    protected final FieldType type;
    protected Field(FieldType type) { this.type = type; }
    public final FieldType getType() { return type; }
    public final boolean mustUpdateCount() { return type.mustUpdateCount(); }
}

class Brewery implements Field {
    Brewery() {
        super(BREWERY);
    }
}

そしてあなたのコードで:

FieldType expectedType = Enum.valueOf(type.toUpperCase());

for (Field f: board.fieldlist) {
    if (field.getType() != expectedType)
        continue;
    if (!f.getOwnedBy().equals(owner))
        continue;
    // Correct type, owned by the correct guy:
    // check that we must update; if so, update
    if (expectedType.mustUpdateCount())
        count++;
}
于 2013-01-06T23:37:33.447 に答える
1

ShippingBreweryはから派生しているのでFieldFieldのようなタイプを示すゲッターを提供できますgetFieldType()Shippingまたはがインスタンス化されるとBrewery、適切な値が設定されます。または、getFieldType()抽象化してそれらShippingBrewery実装します。

于 2013-01-06T23:38:01.623 に答える
1

Shipping.classクラスを表す文字列の代わりにまたはを関数に渡しBrewery.class、フィールドがそのクラスに属していることを確認します。

public static int getNumberOfOwned(Player owner, Class<? extends Field> type){
    int count = 0;      
    for (Field f: board.fieldList) {
        if (type.isInstance(f) && f.getOwnedBy() == owner) {
            count++;
        }   
    }
    return count;
}
于 2013-01-06T23:41:09.590 に答える
1

最善の解決策は、この問題に対して訪問者パターンを使用することです。ここで調べることができます:訪問者パターン

少なくとも問題を処理するオブジェクト指向の方法ですが、現在のソリューションよりも多くのコーディングが必要になることは確かです。

于 2013-01-06T23:45:12.373 に答える
0

isType(String type)フィールドに""メソッドを追加します。isOwnedBy(String owner)さらに言えば、フィールドにも「」を追加します。

for (Field f: board.fieldList)
    if (f.isType(type) && f.isOwnedBy(owner))
        count++;
return count;
于 2013-01-06T23:38:50.730 に答える
0

まず第一に、「==」演算子を使用してオブジェクトの等価性をテストしていることをアドバイスしてください。これはほとんどの場合間違っており、この場合は間違いなく間違っています:)

オブジェクトが特定のタイプであるかどうかを判断したい場合は、instanceof 演算子を使用できます。それらが同じクラス参照を持っているかどうかを確認するか (ここでは "==" 演算子を使用できます)、キャストを試して例外を確認します。最後のオプションは、現実の世界ではこれを試してはならないため、より幻想的です。

あなたが何をしようとしているのかよくわかりませんが、次のようなインスタンス/クラス/キャストを避けるようにオブジェクトを調整することは間違いありません。

class Foxtrot implements Sub {
    private  SubType type = SubType.ATACK;

    public SubType getType() {
        return type;
    }
}

interface Sub {
    enum SubType{ ATACK, BOOMER }

    public SubType getType();
}

また、オブジェクトを Sub インターフェイスの実装として扱い、その getType() メソッドでオブジェクトの種類を確認できます。ほとんど機能するはずです。

于 2013-01-06T23:47:09.030 に答える
-1

このコードを書き直す必要があります

1)クラスフィールド追加メソッドgetType();

2)コード:

public static int getNumberOfOwned(Player owner, String type){
  int count = 0;      
  for (Field f: board.fieldList){
    if (f.getType.equals(type)&& f.getOwnedBy().equesl(owner))
    count++;
  }
  return count;

}

于 2013-01-06T23:42:27.763 に答える
-1

string getTypeString()Fieldのプロパティを作成し、大量のifステートメントを使用しないようにします(チェック) 。getOwnedBytype.equals(f.getTypeString())をFieldのプロパティにし、キャストを使用しないでください。(所有者がいないフィールドはnullを返すことができます)

于 2013-01-06T23:43:09.540 に答える