4

次の違いがわかりません:

  1. ArrayList<Integer> list = new ArrayList<Integer>();
  2. Collection<Integer> list1 = new ArrayList<Integer>();

ClassArrayListは interface を実装するクラスを拡張するCollectionため、 Classは interface をArrayList実装しCollectionます。インターフェイスlist1から静的メソッドを使用できるようにすることはできCollectionますか?

4

5 に答える 5

12

インターフェイスには [Java 7 の] 静的メソッドはありません。list1では のメソッドのみにアクセスできますがCollectionlistでは のすべてのメソッドにアクセスできますArrayList


可能な限り具体的でない型で変数を宣言することをお勧めします。したがって、たとえば、または何らかの理由で変更ArrayListした場合、コードの大部分 (クライアント クラスなど) をリファクタリングする必要はありません。LinkedListHashSet

次のようなものがあると想像してください(説明のみを目的としており、コンパイルできません):

class CustomerProvider {
    public LinkedList<Customer> getAllCustomersInCity(City city) {
        // retrieve and return all customers for that city
    }
}

そして、後でそれを実装して を返すことにしましたHashSetLinkedListを返すという事実に依存し、持っていないメソッドを呼び出すクライアント クラスがあるかもしれHashSetません (例: LinkedList.getFirst())。

そのため、次のようにする方がよいでしょう。

class CustomerProvider {
    public Collection<Customer> getAllCustomersInCity(City city) {
        // retrieve and return all customers for that city
    }
}
于 2013-01-04T19:08:47.707 に答える
2

他の人が言っているように、違いは、Collection変数タイプとして指定する場合、インターフェイスによって定義されたメソッドに制限されることです。しかし、それはなぜあなたがこれをしたいのかという質問に答えません。

その理由は、データ型の選択がコードを使用する人々に情報を提供するためです。特に、パラメーターまたは関数からの戻り型として使用される場合(外部プログラマーが内部にアクセスできない場合)。

特異性の高い順に、さまざまなタイプの選択からわかることがあります。

  • Collection-オブジェクトのグループ。これ以上の保証はありません。このオブジェクトのコンシューマーは、コレクションを反復処理でき(反復順序についての保証はありません)、そのサイズを学習できますが、それ以外のことはできません。
  • List-特定の順序を持​​つオブジェクトのグループ。これらのオブジェクトを反復処理すると、常に同じ順序で取得されます。インデックスによってコレクションから特定のアイテムを取得することもできますが、そのような取得のパフォーマンスについて推測することはできません。
  • ArrayList-特定の順序を持​​ち、一定時間でインデックスによってアクセスされる可能性のあるオブジェクトのグループ。

そして、あなたはそれらについて尋ねませんでしたが、ここにいくつかの他のコレクションクラスがあります:

  • Setメソッドごとに重複が含まれないことが保証されているオブジェクトのグループequals()。これらのオブジェクトの反復順序に関する保証はありません。
  • SortedSet重複を含まず、常に特定の順序で反復されるオブジェクトのグループ(ただし、その特定の順序はコレクションによって保証されません)。
  • TreeSet重複のない順序付けられたオブジェクトのグループで、O(logN)挿入時間と取得時間を示します。
  • HashSet重複のないオブジェクトのグループ。固有の順序はありませんが、(償却された)一定時間のアクセスを提供します。
于 2013-01-04T19:57:50.293 に答える
2

ここで扱っているのは、interfaceimplementationの違いです。

インターフェースは、それらのメソッドがどのように実装されているかに関係なく、一連のメソッドです。実際に である型を持つオブジェクトをインスタンス化するとき、interface私たちが言っているのは、それはその中のすべてのメソッドを実装するオブジェクトであるということinterfaceです...しかし提供しないのは、中のメソッドのいずれにもアクセスできませんclass実際にそれらの実装を提供する。

実装の型でオブジェクトをインスタンス化すると、classその の関連するすべてのメソッドにアクセスできますclass。これclassは を実装しているためinterface、インターフェイスで指定されたメソッドに加えて、実装クラスによって提供されるすべてのエクストラにアクセスできます。

なぜこれをしたいのですか?オブジェクトの型を に制限するinterfaceことで、コードの残りの部分を変更することを心配することなく、新しい実装に切り替えることができます。これにより、はるかに柔軟になります。

于 2013-01-04T19:13:26.033 に答える
1

唯一の違いは、Collection インターフェイスを介して list1 へのアクセスを提供しているのに対し、ArrayList インターフェイスを介して list2 へのアクセスを提供していることです。カプセル化を促進し、実装の詳細への依存を減らすという点で、制限されたインターフェイスを介してアクセスを提供すると便利な場合があります。

于 2013-01-04T19:09:09.783 に答える
0

「list1」で操作を実行すると、Collection インターフェイスからのメソッド (get、size など) にのみアクセスできます。「list」を ArrayList として宣言すると、ArrayList クラスでのみ定義されている追加のメソッド (ensureCapacity や trimToSize など) にアクセスできるようになります。

通常、必要な最も具体的なクラスとして変数を宣言することをお勧めします。したがって、コレクションのメソッドのみが必要な場合は、それを使用してください。通常、この場合、それは List を使用することを意味します。これにより、順序付けられていることがわかり、重複を処理できます。

固有性が最も低いクラス/インターフェースを使用すると、後で実装を自由に変更できます。たとえば、後で LinkedList を使用する方が適切な実装であることがわかった場合、変数を List として定義すると、すべてのコードを壊さずに変更できます。

于 2013-01-04T19:10:59.823 に答える