2

私はそのようなリスト構造のセットアップを持っています:

List<List<Value>> l = new RowList();

エラーが発生し"Type mismatch: Cannot convert from RowList to List<List<Value>>"ます。実装は次のとおりです。

public class RowList extends ArrayList<ValueList>
public class ValueList extends ArrayList<Value>

値は私のコードベースのオブジェクトです。これが機能しないのはなぜですか?代わりにこれを使用すると、すべて正常に動作します:

public class RowList extends ArrayList<List<Value>>

私が取り組んでいる大学の課題について、私たちの講師が書いたList<List<Value>>コードは、私のコード内でa を返すメソッドを呼び出し、List<Value>そのリストに追加することによって機能します。プログラムはデータベースを実装することを意図しているため、キー値が複数回発生しないなど、多くの要件があります。これが発生していないことを確認するには、ValueList クラスまたは同様のものを使用できる必要があります。そのため、add()これらの要件を確認するメソッドを拡張できます。

これは正しい方法ではないように思えますが、これを行うコードを変更することは許可されていないため、私には選択の余地がありません。ジェネリックについて考えさせられるという考えだと思います。

4

2 に答える 2

8

そもそもコレクションのサブクラスを作成するのは悪い考えです。標準の実装に固執し、継承ではなく合成を使用してください。

これがコンパイルされない理由を理解するために、短い例を挙げて理由を説明します。あなたがやりたいことが可能でコンパイルされたと仮定すると、次のことができます:

RowList rowList = new RowList();
List<List<Value>> listOfLists = rowList;
listOfLists.add(new LinkedList<Value>());

また、RowList はValueListonly のインスタンスを保持することになっていますが、LinkedList<Value>内部にあるため、プログラムの型安全性と正確性が損なわれます。

于 2013-05-24T07:59:40.573 に答える
1

問題は、 でRowListはないList<List<Value>>ため、List<List<Value>> l = new RowList();有効ではありません

これができないのと同じように:

List<Object> objList = new ArrayList<String>();

いくつかの選択肢があります:

l の宣言を List に変更します。

List<ValueList> l = new RowList();

またはワイルドカードを使用する:

List<? extends List<Value>> l = new RowList();

編集:上記のアプローチで解決できますが、設計をより適切にリファクタリングする必要があります。継承を使用して C/C++ のようなことをしようとしていると思いますが、継承をtypedef使用して typedef をシミュレートすることの副作用は大きく (少なくとも Java では)、それを行う前によく考えてください。本当に理にかなっている場合 (つまり、本当にValueListis-a が必要な場合List<ValueList>) に継承を使用すべきではないと言っているわけではありません。List<Value>ただし、意味のある型を導入するのではなく、単に入力を節約するためにそうしているように思えます。

于 2013-05-24T09:36:59.033 に答える