- PR -

インスタンスの生成

投稿者投稿内容
Kira
ぬし
会議室デビュー日: 2004/10/30
投稿数: 252
投稿日時: 2004-11-06 00:56
いつも勉強させていただいてます。

今までインスタンスを生成するときには
HashMap a = new HashMap()
先頭と最後のクラス名はおまじないのごとく同じにしていました。

しかし以下のような文をみて実行したところエラーになりませんでした。
Map map=new HashMap()
これはどういう意味をしめすのでしょうか?
同じでなくでもいいのでしょうか?
tata
会議室デビュー日: 2004/09/06
投稿数: 19
投稿日時: 2004-11-06 02:00
プリミティブ型(intやdoubleなど)同士の代入処理と同じように、参照型同士の代入処理(*)もできます。

ここで、Mapとはインターフェイスです。HashMap(クラスです)はMapを継承しています。Map「親」−HashMap「子」という関係にあります。このように親子関係(is-a関係、継承関係ともいいます)が成立する場合、参照型同士の代入処理(*)ができます。

ちなみにこの代入処理(*)を参照型キャストといい、その方法として明示的キャストと暗黙キャストがあります。

(*)参照型変数(YOUさんの投稿ではaとmap)は実際は代入ではなく参照といいます。プリミティブ型は代入です。

親子関係についてはココ見てください。
http://java.sun.com/j2se/1.4/ja/docs/ja/api/java/util/package-tree.html
na2fusi
会議室デビュー日: 2003/06/08
投稿数: 16
投稿日時: 2004-11-06 02:45
APIドキュメントでMapとHashMapのクラス宣言部分を見れば分かると思いますが
Map:public interface Map
HashMap:public class HashMap extends AbstractMap
implements Map, Cloneable, Serializable

HashMapはMapを実装していることが分ります。
このような場合子クラスHashMapを親クラスMapのインスタンスとして扱うことが可能です。

実際のJavaプログラム開発では
使用する子クラスを動的に切り替え子クラスごとに挙動を変える「ポルモルフィズム(多態性)」を利用することはよくあることです。
「ポルモルフィズム」を学びますと
引用:
Map map=new HashMap()


のようにコードを書くことの利点も分かってくるかと思います。
Javaの世界が広がるでしょう。

class SuperClass {
public static void main(String[] args) {
SuperClass class = new SubClassX(); X:A or B
class.method();←classがSubClassAとBのときで挙動が異なる。
}
void method(){}
}
class SubClassA extends SuperClass {
void method() {System.out.println("A");}
}
class SubClassB extends SuperClass {
void method() {System.out.println("B");}
}
Kira
ぬし
会議室デビュー日: 2004/10/30
投稿数: 252
投稿日時: 2004-11-06 11:33
ありがとうございます。

new の後のクラスが、Map型の子クラスの場合は
入れ替えて変数の使い回しがきくということでしょうか?

Map map = new HashMap();
map = new TreeMap();
syo
常連さん
会議室デビュー日: 2003/08/17
投稿数: 43
投稿日時: 2004-11-06 12:11
お世話になっております。

引用:

YOUさんの書き込み (2004-11-06 11:33) より:

new の後のクラスが、Map型の子クラスの場合は
入れ替えて変数の使い回しがきくということでしょうか?



 結果的にそういうことも可能ではありますが、やはりna2fusiさんの仰っている「クラスの切り替え」の方がメインとなってくるのではないかと思います。

 メソッドの引数も含めて考えると、そのメリットが感じられるかもしれません。
コード:
private void hoge_1(Map m) {
  //  引数の内容を用いた何らかの処理
}
private void hoge_2(HashMap m) {
  //  引数の内容を用いた何らかの処理
}
public void exec() {
  HashMap map = new HashMap();
  //  何らかの処理
  hoge_1(map);
  hoge_2(map);
}


というようなコードがあった場合で、後で「HashMapではなくてやっぱりTreeMapを使おう」と思ってexecメソッドを修正するときに効果が出てきます。
 hoge_1メソッドは引数がMapなので、そのまま通りますが、hoge_2は引数がHashMapなので、そのままではTreeMapを渡すことができずにhoge_2の修正(あるいは新規メソッドの追加)が必要となってきます。
YOU@IT
ぬし
会議室デビュー日: 2002/03/29
投稿数: 284
お住まい・勤務地: 大阪
投稿日時: 2004-11-06 14:49
引用:

YOUさんの書き込み (2004-11-06 11:33) より:
new の後のクラスが、Map型の子クラスの場合は
入れ替えて変数の使い回しがきくということでしょうか?



変数の使いまわし、は考えないほうがよいと思います。
変数は必要最低限のスコープで、適宜、適切な名前をもって宣言すべきと思っています。

たとえば、

List birds = new ArrayList();
/* 鳥の処理 */
birds = new ArrayList();
/* 魚の処理 */

のように変数birdsを使いまわすと、魚の処理であるにもかかわらず
変数名は鳥を示しています。これは不自然ですよね。

じゃぁ変数をbirdsなんて具体的な名前ではなく、listのような
意味のない名前にすれば良いじゃん、と思われるかもしれませんが、
そうするとlistに何が入っているのか推測できなくなり、
保守性が著しく低下します。

と、話がそれてますが、要は変数の使いまわしはしないほうが良いですよ、
てことだけです。
Kira
ぬし
会議室デビュー日: 2004/10/30
投稿数: 252
投稿日時: 2004-11-06 16:54
引数がHashMapの場合とTreeMapの2通りがあって
その処理が同じ場合は
2つメソッドをつくるより
1つのメソッドをつくり引数をMapにしたほうがいいということですか?

極端な話 引数Objectにしてキャストしまえばいいということですか?
bun
常連さん
会議室デビュー日: 2004/11/06
投稿数: 20
投稿日時: 2004-11-06 17:49
na2fusiさんが先におっしゃっていますが

引用:

na2fusiさんの書き込み (2004-11-06 02:45) より:

HashMapはMapを実装していることが分ります。
このような場合子クラスHashMapを親クラスMapのインスタンスとして扱うことが可能です。

実際のJavaプログラム開発では
使用する子クラスを動的に切り替え子クラスごとに挙動を変える「ポルモルフィズム(多態性)」を利用することはよくあることです。
「ポルモルフィズム」を学びますと
引用:
Map map=new HashMap()


のようにコードを書くことの利点も分かってくるかと思います。
Javaの世界が広がるでしょう。




クラスの継承について、お勉強されたら良いと思います。
下記の内容を熟読されてみてはいかがでしょうか?

http://www.atmarkit.co.jp/fjava/rensai2/javaent04/javaent04.html#ap02

スキルアップ/キャリアアップ(JOB@IT)