0

だから私は3つのクラスがあります:

  • Item
  • GroupItem 伸びる Item
  • ProductItem 拡張アイテム

オブジェクトの配列をItemクラスに渡し、クラス タイプに応じて個別に処理したいと考えています。

これを行うのに許容できる方法を使用するか、指定されたサブクラスの初期化時に設定されるinstanceof内部メソッドを使用する必要があります。boolean isGroup()

 class Item {
      protected boolean isGroup = false;
      public boolean isGroupItem() { return isGroup; }
 }

 class GroupItem extends Item {
      public GroupItem() {
           isGroup = true;
      }
 }

 class ProductItem extends Item {
      public ProductItem() {
           isGroup = false;
      }
 }


 class Promotion {
      // Item can be either a group or a list of items
      private List<Item> items = new LinkedList<Item>;
      public void addItem(Item itemObj) {
           items.addItem(itemObj);
      }
      public List<Item> getItems() {
           return items;
      }
 }



 class Checker {
      // Items retrieved from Promotion and passed from another class as array
      public Checker(Item[] items) {
           // either

           if(items[0] instanceof GroupItem) {
                // Do something ...
           }

           // or

           if(items[0].isGroupItem()) {
                // Do something ...
           } 
      }
 }

だから私の質問は:

  • インスタンスまたはメソッド?
  • メソッドの場合、アイテムまたはプロモーションで?
  • なぜ?(理由がよくわかるように)

前もって感謝します

4

5 に答える 5

3

パラメータとして渡したい実際の型に対して異なるメソッドを使用します。

通常、使用instance ofは、モデルに問題があることを意味します。

サブタイプごとに異なる動作が必要な場合は、実際には親タイプを使用していないことを意味します。さらに、実装の詳細を知る必要がありますが、そうではありません。

継承が技術的なものにすぎない場合は、継承の代わりに構成を使用してください

于 2013-05-10T09:00:44.400 に答える
2

instanceOfこれは、 operatorを使用する正確な場所です。

instanceof 演算子は、オブジェクトを指定された型と比較します。これを使用して、オブジェクトがクラスのインスタンス、サブクラスのインスタンス、または特定のインターフェイスを実装するクラスのインスタンスであるかどうかをテストできます。

これを行うために新しいメソッドやブール値のプロパティをスケッチする意味はありません。GroupIteminstanceOf をチェックすることで、特定のオブジェクトを簡単に識別できます。

GroupItem.class.isInstance(items[0])を使用して同じことを確認することもできます。お気に入り -

if(GroupItem.class.isInstance(items[0])) {
      // Do something ...
}
于 2013-05-10T08:53:49.957 に答える
1

この時点で、グループであるかどうかを知る必要がある理由を定義しようと思います。

1 つのアイテムがプロモーションの対象であり、プロモーション ルールが変更される可能性があるかどうかを判断するとします。instanceofプロモーション ルールのロジックによって基本オブジェクトが「汚染」されることを望まないため、 を使用します。

グループであることはアイテムの重要なプロパティであり、(プロモーション ルールだけでなく) さまざまなコンテキストで役立つ場合は、アイテム レベルに含めます。

于 2013-05-10T08:55:07.387 に答える
1

operatorの方が良い選択ですが、 Visitor パターンinstaceOfの使用も検討します。

interface Item{
   void accept(CheckerVisitor checker); 

}

class GroupItem implements Item{

    void accept(CheckerVisitor checker){
        checker.visit(this);
    }

}


class OtherItem implements Item{

    void accept(CheckerVisitor checker){
        checker.visit(this);
    }

}

class CheckerVisitor{

    void visit(GroupItem groupItem){
        //do specific things to GroupItem
    }

    void visit(OtherItem otherItem){}
}

class MyClassOfItems{
    List<Item> items = ...;
    for(Item item : items){
        item.accept(new CheckerVisitor());
    }
}
于 2013-05-10T08:56:00.630 に答える
0

したがって、これを読んだ後、私は自分のソリューションに別の道を選びました。助けてくれたみんなに感謝します。

私が選択したソリューションにより、必要な情報だけを取得するために抽象クラスを使用するため、オブジェクトのサブタイプに悩まされることさえありません (自分の構造を再考させてくれた Assylias と Balázs Mária Németh に感謝します)。

 abstract class Item {
      public Item(...) {
           initialise();
           createSQLSegment();
      }

      protected String SQLSegment = "";
      protected abstract void createSQLSegment();
      public String getSQLSegment() {
           return SQLSegment;
      }

      ...
 }

 // Concrete class creates response
 class GroupItem extends Item {
      ...
      // Concrete method
      protected void createSQLStatement() {
           SQLStatement = "...SQL...";
      }
 }

 class ProductItem extends Item {
      ...
      // Concrete method
      protected void createSQLSegment() {
           SQLSegment = "...SQL..."
      }
 }


 class Promotion {
      // Item can be either a group or a list of items? extends Item>;
      public void addItem(Item itemObj) {
           items.addItem(itemObj);
      }
      public List<Item> getItems() {
           return items;
      }
 }



 class Checker {
      // Items retrieved from Promotion and passed from another class as array
      public Checker(Item[] items) {
           ...

           for(Item item : Items) {
                addPreparedSQLToBatch(item);
           }
      }

      private void addPreparedItemToBatch(Item item) {
           ...

           // No need to know concrete class
           SQLString += Item.getSQLSegment();

           ...
      }
 }

皆さんに改めて感謝します。

コメント歓迎、いつも勉強中です :-)

于 2013-05-10T10:16:56.277 に答える