2

次のような状況で、またはそのためにgeneric list機能するものを作成する必要があります。List<ClassA>List<ClassB>

if(e instanceof A)
return A;
else
return B

List Resultしかし、またはのいずれList<ClassA> Resultかとして機能できるものを設定したいのですList<ClassB> Resultが、ここでジェネリックを使用できると確信していますが、使用方法がわかりませんか?

アップデート

私がやりたいのはそのランタイムだけです、私のリストには適切なタイプが入力されている必要がありますclass A or class B、、

if()
{
    //data is present in List<ClassA> classAList = new ArrayList<ClassA>();
    //return classAList
}
else
{
  //return List<ClassB> classBList = new ArrayList<ClassB>();
}

お役に立てれば。

4

8 に答える 8

2

したがって、私があなたを正しく理解している場合は、特定のオブジェクトがClassAであるかClassBであるかに応じて、ClassAのリストまたはClassBのリストを作成できるようにする必要があります。

public List<? extends Object> getList(Object e) {
    List<? extends Object> list = new ArrayList<? extends Object>();
    if(e instanceof ClassA) {
        List<ClassA> listA = new ArrayList<ClassA>();
        // Populate list somehow
        list = listA;
    } else if (e instanceof ClassB) {
        List<ClassB> listB = new ArrayList<ClassB>();
        // Populate list somehow
        list = listB;
    }
    return list;
}

残念ながら、returnタイプはどちらのタイプも許可する必要があります(代わりに、異なるreturnタイプで2つのメソッドを作成できますが、それらは異なる名前である必要があります)。ただし、これにより、listAとlistBをより一般的なリストに割り当てる前に、それらを独自のタイプとして使用できます。

ただし、これはSOLIDプリンシパルの違反であるため、代替手段は次のようになります。

public abstract class Root<T> {
    public abstract List<T> getList();
}

public class ClassAList extends Root<ClassA> {
    @Override
    public List<ClassA> getList()  {
        List<ClassA> list = new ArrayList<ClassA>();
        // Populate list somehow
        return list;
    }
}

public class ClassBList extends Root<ClassB> {
    @Override
    public List<ClassB> getList()  {
        List<ClassB> list = new ArrayList<ClassB>();
        // Populate list somehow
        return list;
    }
}

お役に立てば幸いです。

于 2012-04-26T14:58:31.147 に答える
1
class A extends C{ ... body ... }
class B extends C{ ... body ... }

//動作します

List<C> list = new ArrayList<C>();
list.add(new A());
list.add(new B());

またはによる提案Bernard

概要 :

オプションは、親クラスを作成してから親クラスを拡張し、親タイプをリストAB 追加するか、インターフェイスを作成してそのインターフェイスをから実装し、AインターフェイスBタイプをリストに追加することです。いずれにせよ、クラスを変更して、A新しいBインターフェイスまたはクラスを作成することになります。

于 2012-04-26T14:43:42.933 に答える
1

両方のクラスが実装する共通のインターフェースを使用する必要があります。インターフェイスがと呼ばれているとしMyInterfaceます。どちらのクラスもこのインターフェースを実装でき、ジェネリックリストはタイプにすることができますList<MyInterface>

別の方法は、両方のクラスに共通の基本クラスがあることです。

編集:

OPの要求に応じていくつかの例を追加しました。

インターフェースの例:

public interface MyInterface
{
   String getName();

   void setName(String name);
}

インターフェイスの実装例:

public class ClassA implements MyInterface
{
   private String name;

   public String getName()
   {
      return name;
   }

   public void setName(String name)
   {
      this.name = name;
   }
}

一般的なリストの使用例:

List<MyInterface> list = new ArrayList<MyInterface>();

list.add(new ClassA());

MyInterface item = list.get(0);

item.setName("Bob");

String name = item.getName();
于 2012-04-26T14:43:52.230 に答える
0

ClassAとClassBに共通の基本クラスがある場合(つまり、両方が同じクラスを拡張する場合)、ジェネリックパラメーターで基本クラスタイプを使用できます。

于 2012-04-26T14:43:05.757 に答える
0

ジェネリックは基本的に静的時間チェック用です。あなたの場合、2種類のデータがあるため、AとBが共通の祖先クラスを共有しない限り、ジェネリックを使用しても意味がありません。

于 2012-04-26T14:43:34.523 に答える
0

これを行う唯一の方法は、共通の親クラスClassAClassB持つか、共通のインターフェースを実装することです。いずれの場合も、リストをそれらの特定のクラスに制限する唯一の方法は、他のクラスにその共通の親または共通のインターフェースがない場合です。

これらは両方とも、この共通の親または共通のインターフェースがすでに存在するか、およびを制御できる必要がClassAありClassBます。彼らがそうしない、そしてあなたがそうしないなら、あなたが求めていることをする方法はありません。

于 2012-04-26T14:44:23.117 に答える
0

これは、共通の親Aを共有している場合にのみ実際に可能です(たとえば)。その後、を返すことができます。BCList<C>

返品することは可能List<Object>ですが、これに反対し、デザインを作り直すことを検討することをお勧めします。

于 2012-04-26T14:44:44.150 に答える
0

おそらくこのようなもの:

public class Test {
  static class A {}
  static class B {}
  private static List<?> getList() {
    List<A> aList = new ArrayList<A>();
    List<B> bList = new ArrayList<B>();
    aList.add(new A());
    if (aList.size() > 0) {
      return aList;
    } else {
      return bList;
    }
  }

  public static void main(String[] args) {
    List<?> cList = getList();
    System.out.println(cList);
  }
}
于 2012-04-26T19:15:56.657 に答える