みんなの「教えて(疑問・質問)」にみんなで「答える」Q&Aコミュニティ

こんにちはゲストさん。会員登録(無料)して質問・回答してみよう!

解決済みの質問

javanoリストのオブジェクト作成について

リストのオブジェクトを作成するときに、

(1) List<Person> list = new ArrayList<Person>();
(2) ArrayList<Person> list = new ArrayList<Person>();

と二つの宣言の仕方をよく見かけるのですが、この二つは
何が違うのでしょうか。また、どのような場合にそれぞれ
使われることが多いのでしょうか。

投稿日時 - 2009-07-30 00:56:02

QNo.5166792

すぐに回答ほしいです

質問者が選んだベストアンサー

例えばこんな感じです。

know_smthgさんが、「リンゴの皮をむく人」をコーディングしたとします。メソッドは、peel(Apple apple)です。

今度は、ナシの皮を向く人が必要になったとしましょう。また新たにナシの皮をむくコードを書くこともできますが、それでは二度手間です。

リンゴの皮をむくのも、ナシの皮をむくのも、みかんの皮をむくのも同じようにできるのなら、この際リンゴとナシとみかんに、「丸い果物」というインターフェースをimplementさせて、peel(RoundFruit rf)というメソッドを書いたほうが便利です。

この話では、ArrayListがリンゴ、Listが「丸い果物」にあたります。

一般に、コードは扱う対象について、最小限のことしか知らないようにコーディングすることが好ましいとされています。ほかの事は知らなくてもいいのだから、当然知らなくて損をすることはないし、知らなければ知らないほど一般に変更に強くなるからです。

例えば、上記の例では、別に「果物」であることをむく人が知る必要はないので、「丸くてむける」というインターフェースの作り方をすれば、じゃがいもにも使えてなお再利用性が向上するでしょう。


しかし、「知らない」コードを書くのは「知っている」コードを書くより大変で、複雑になりがちなので、むやみに「知らない」コードを書こうとしてプログラムを複雑にしないように気をつけなければいけません。低いコスト(時間、複雑性、パフォーマンスなど)で知らないコードを書けるなら、当然そうする、高いコストでしかかけないなら、将来変更が予想される場合にだけ知らないコードを頑張って書く、というのがベストプラクティスとされています。

投稿日時 - 2009-08-01 08:38:33

このQ&Aは役に立ちましたか?

1人が「このQ&Aが役に立った」と投票しています

回答(3)

ANo.2

1の宣言を強く推奨します

インターフェースの活用により、
プログラミングの自由度が格段に上がると思います。

最初のうちは気がつかないかもしれませんが、
今は習慣として1を心がけてください
これはオブジェクト指向の醍醐味の一つです。
投稿者さんはオブジェクト指向をまだ理解できていないのですね。

説明するより、経験で体得できると思います
そのうち、ソートしたくなったりHashに変換したくなるときが
来ると思います。 そうなると理解できると思います。

この回答スペースでは足りないので
http://java.sun.com/javase/ja/6/docs/ja/technotes/guides/collections/index.html
を参照してください

がんばって

投稿日時 - 2009-07-31 22:54:36

ANo.1

■基本的に(1)を使っています。
Listはインタフェースで、ArrayListはこのListインタフェースを実装したクラスです。
したがって、ArrayListクラスにはListインタフェースで宣言されているメソッドが実装されていることが保証されます。
Javaの標準クラスにはLinkedListなどListインタフェースを実装したクラスが他にもあります。
http://java.sun.com/javase/ja/6/docs/ja/api/java/util/List.html


■ArrayListクラスには、Listインタフェースで宣言されているメソッドの他にもメソッドが定義されています(例.trimToSizeメソッド)。
そのようなメソッドを呼ぶ必要が本当にある場合は、(2)のように記述してそのメソッドを呼ぶことになるのだと思います。
ちなみに自分が(2)のように記述する必要に迫られたことは記憶にないです :)
ArrayList<Person> personArrayList = new ArrayList<Person>();
personArrayList.trimToSize(); //呼ぶことができる。

List<Person> personList = new ArrayList<Person>();
personList.trimToSize(); //コンパイルエラー


■(1)のようにListインタフェースを使う方が良いとされる理由を説明するのは自分には難しいのですが、
「インターフェイスプログラミング」「疎結合」などがキーワードになると思います。
例えば、Listインタフェースの実装クラスをArrayListから
LinkedListなどの他のListインタフェースを実装するクラスに変更したい場合、(1)の方が簡単です。

▼(1)でArrayListからLinkedListに変更する場合、ArrayListをLinkedListに変更するだけでよい。
List<Person> personList = new ArrayList<Person>(); // new LinkedList<Person>();
//以下、personListの参照先がArrayListなのか
//Listインタフェースを実装した他のクラスなのかを気にする必要はない。
... ...
personList.add(person);


▼(2)でArrayListからLinkedListに変更する場合、
ArrayList<Person> personList = new ArrayList<Person>();

LinkedList<Person> personList = new LinkedList<Person>();
に変更するだけでよいかは以降のコードを調べないとわからない。
次のようにArrayList独自のメソッドが呼ばれているかもしれない。
personArrayList.trimToSize();

人に説明するのは難しいですね :)

投稿日時 - 2009-07-30 06:57:28

あなたにオススメの質問