== クラス == クラスでは'''属性'''(性質)と'''動作'''(機能)を定義します。 属性はデータ構造(データの集まり)とも考えられます。 今回はクラスのデータについて説明します。 ----- 指示に従って作図しなさい。 プログラムを実行しないこと。 {{{#!java public class Card { String suit; int rank; static int sum; public static void main(String[] args) { Card a; Card b; Card c; a = new Card(); a.suit = "ハート"; a.rank = 12; b = new Card(); b.suit = "スペード"; b.rank = 3; c = b; c.rank = a.rank - 2; System.out.println( b.rank ); Card.sum = a.rank + b.rank + c.rank; System.out.println( Card.sum ); } } }}} ---- 1.プログラムの構造を描きます クラス全体を長方形で次のように囲みます。 . {{attachment:class2.png}} クラスの中にあるメソッドを次のように囲みます。 今回はmainメソッド1つしかありませんが、通常は沢山のメソッドがあります。 . {{attachment:class3.png}} ---- 2.宣言されている変数1つに対し1つの長方形を描きます。 . 変数宣言はsuit, rank, sum, a, b, c の6つがあります。 . その横にそれぞれ長方形を描きます。 これらの変数のうち、a,b,cの3つはmainメソッド内のローカル変数です。 . staticなメソッドのローカル変数は、いま長方形を描いたその場所に取られると考えてよい。 . 変数aに代入を行うと、aの横に描いた長方形の中に値(基本データ型の場合は値、オブジェクトの場合は参照)が書かれると考える。 3つの変数 suit, rank, sum はクラスの中にあって、どのメソッドの中にも入っていません。 このうち static変数はクラスの中に取られます。 . sum の値はここに記録されると考えてよい。 saticでない変数はインスタンス内に取られます。 . インスタンスが作成されるときの'''型紙'''として使われます。 . インスタンスはそのクラスのオブジェクトのこと。 . インスタンスごとに別の属性値をとることができる。 suit, rank の2つがこれに該当します。 . 角の丸い点線の長方形で囲みます。 . Cardというクラスオブジェクトの型紙であることを示します。 次のような図になりました。 . {{attachment:card1.png}} このクラスをUMLで描くと次のようになります。 上の図との対応が分かります。 . {{attachment:cardclass.png}} staticな変数には下線を引いて表します。 ---- '''クラス'''は型にあたります。 クラスを利用するには、まずその型(クラス)の変数を用意します。 プログラムの10~12行目の変数宣言では Cardという型(クラス)の変数 a, b, c を準備しています。 ----- 3.プログラムの実行をたどってみる mainメソッドの実行は14行目から始まります。 {{{ a = new Card(); }}} 右辺の new Card() を行い変数aに代入しています。 . '''new クラス名()''' が行われるとそのクラスのオブジェクトが作られます。 Cardはここで定義しているクラスで、そのオブジェクト (インスタンス)は上で描いた型紙と同じ形をした実体です。 . {{attachment:card2a.png}} インスタンスにはクラス名をつけて上のように描くのが正しいのですが、 どのクラスのインスタンスか明らかなときは省略して次のように書くこともある。 . {{attachment:card2.png}} 作られたオブジェクト(インスタンス)を変数aに代入すると、 オブジェクトのアドレスが値として代入されて . {{attachment:card3.png}} 変数aを使って、このオブジェクトを参照できるようになります。 ---- 15,16行目 {{{ a.suit = "ハート"; a.rank = 12; }}} Card型の変数aが参照しているオブジェクト内の変数を参照するには '''オブジェクト名.オブジェクト内の変数名''' のように、2つの名前をピリオドで繋いで書きます。 a.suit = "ハート"; で、変数aが参照しているオブジェクト内の変数suitに、文字列"ハート"を代入します。 a.rank = 12; で、変数aが参照しているオブジェクト内の変数rankに、整数値12を代入します。 . {{attachment:card3a.png}} ---- 18~20行目 {{{ b = new Card(); b.suit = "スペード"; b.rank = 3; }}} 18行目でもうひとつCard型のオブジェクトが作られます。 . 14行目で作られたオブジェクトとは別のオブジェクトです。 オブジェクトはいくつでも作ることができます。 20行目まで実行されると、このようになります。 . {{attachment:card4a.png}} ---- 22行目 {{{ c = b; }}} 変数bの値を、変数cに代入しています。<
> . 変数bはどのオブジェクトを指しているかの情報を保持しています。 . オブジェクトのアドレスを値として持っていると考えてよい。 この値を変数cに代入すると、 変数cは変数bと同じ値をもち、同じオブジェクトを参照することになります。 . {{attachment:card4b.png}} ---- 23行目 {{{ c.rank = a.rank - 2; }}} 代入文です。 . 右辺の値を計算します。 . 変数aが参照しているオブジェクト内の変数rankの値から2を引いて、値は10となります。 . 左辺で指定した変数に、この値を代入します。 したがって 変数cが参照しているオブジェクト内の変数rankに、値10が代入されます。 ここまでの結果を図示するとこのようになります。 . {{attachment:card4.png}} ---- 25行目 {{{ System.out.println( b.rank ); }}} 変数bが参照しているオブジェクト内の変数rankの値を表示します。 変数bとcは同一のオブジェクトを参照しています。 この時点では b.rank の値は10になっています。 ---- 27行目 {{{ Card.sum = a.rank + b.rank + c.rank; }}} 変数aが指しているオブジェクトのrankの値と、 変数bが指しているオブジェクトのrankの値と、 変数cが指しているオブジェクトのrankの値を足し算し、 結果を クラスCardのstatic変数sumに代入します。 . 値は 12 + 10 + 10 で 32 同じクラス内ではクラス名を省略して . sum = a.rank + b.rank + c.rank; と書いても良い。