== メソッド == クラスのもつ機能を定義したものをメソッドといいます。 メソッドはオブジェクトに対する(オブジェクトを利用した)処理を記述したものとも言えます。 Drinkクラスのメソッドを定義してみましょう。 . {{attachment:drink.png}} クラス図には次の4つの機能(メソッド)が書かれています。 . Drink(...) . disp( ) . setYoryo( ) . getYoryo(...) クラス名と同じ名前のメソッドはコンストラクタと呼ばれ、別の機能を持ちます。次ページで解説。 このページでは普通のメソッドについて解説します。 ---- === メソッドの定義 === {{{#!java public class Drink extends Item { int yoryo; void disp() { System.out.printf("%s \\%d %d ml\n", this.namae, this.kakaku, this.yoryo ); } public static void main(String[] args) { Drink a; Drink b; a = new Drink(); a.namae = "麦茶"; a.kakaku = 120; a.yoryo = 500; b = new Drink(); b.namae = "紅茶"; b.kakaku = 130; b.yoryo = 500; a.disp(); b.disp(); } } }}} Drinkクラスのメソッドとして disp を定義しました。 . 値を返さないので、メソッドの型にはvoidと書きます。 . 本体は次の1行で、動作はオブジェクトの namae, kakaku, yoryo 3つの値の表示です。 {{{ System.out.printf("%s \\%d %d ml\n", this.namae, this.kakaku, this.yoryo ); }}} . (注) バックスラッシュは日本語コードでは円マークです。 ---- === メソッドの使い方 === 値を返さないメソッドの使い方は '''インスタンス.メソッド();''' です。 {{{ a.disp(); }}} のように、インスタンスとメソッド名をピリオドでつなぎ後ろに括弧を書きます。 void(値を返さない)型のメソッドの場合 インスタンスxxxに対してメソッドyyy()を行う のように解釈すればよい。 この場合は「インスタンスaに対してdisp()を行う」と読めます。 ---- === メソッドの動作 === メソッドが  インスタンス.メソッド(); として呼び出されると、このときのインスタンスの値が this に対応付けられてから、 メソッド本体が実行されます。 25行目の . a.disp(); ではaの値がthisに渡されて実行されるので、aが参照しているDrinkインスタンス内の3つの変数の値が表示されます。 . {{attachment:drink2.png}} 26行目の . b.disp(); ではbの値がthisに渡されて実行されるので、bが参照しているDrinkインスタンス内の3つの変数の値が表示されます。 ---- === 値を修正するメソッド === メソッド内で、thisが指しているオブジェクト内の変数の値を修正することもできます。 setYoryoメソッドだけを示します。 dispメソッドと同様の位置に追加してください。 {{{#!java void setYoryo(int ryo) { this.yoryo = ryo; } }}} このメソッドは引数をとるので、呼び出し側でも引数の指定が必要です。 mainメソッド内で {{{ b.setYoryo(250); }}} を行うと、 bの指しているオブジェクト内の変数yoryoの値が250に修正されます。 ---- === 値を返すメソッド === 値を返すメソッドは次のように記述します . メソッド定義の先頭で返す型を指定 . メソッド本体ではreturn文を使って値を返す {{{#!java int getYoryo() { return this.yoryo; } }}} . この例では値を返すことしかしていませんが、通常はその前に計算などの処理が入ります。 値を返すメソッドは計算式の中で使えます。 呼び出し方は同じです。 {{{ System.out.println( a.getYoryo() ); }}} ----- === setYoryo(), getYoryo() === こんなメソッドを使わなくても、オブジェクト内の変数を直接参照すれば同じ処理が簡単に書けます。 小さなプログラムの場合はそれでかまいませんが、 大きなプログラムや堅牢性が要求される場合には、この形のメソッドが多用されます。 値の参照や修正をメソッドを使って行うようにすれば、 オブジェクトの状態をすべてクラス内で管理できるからです。 ---- === this === thisはキーワードです。 変数のように見えますが代入することはできません。 あいまいさが無いときはthis.を省略することができます。 このページで示したメソッドではthis.がなくてもどの変数を指しているか明らかなので省略して {{{#!java void disp() { System.out.printf("%s \\%d %dml\n", namae, kakaku, yoryo ); } }}} のように書けます。 thisを使って次のように書くこともしばしば行われます。 {{{ void setYoryo(int yoryo) { this.yoryo = yoryo; } }}} yoryoという同じ名前がありますがthisを使うことで区別ができます。 . yoryoは引数 . this.yoryoはインスタンス内の変数 ----- === メソッドの継承 === スーパークラスで定義されたメソッドはサブクラスでも利用できます。 {{{#!java public class Item { ... void dispName() ... } }}} 例えば、スーパークラスであるItemクラスでメソッドdispNameme()が定義されている時を考えます。 Drinkクラスのインスタンスに対してdispNameme()メソッドの呼び出しが行われたらどうなるでしょうか。 サブクラスであるDrinkクラスでメソッドdispNameme()が定義されているかどうかで処理が異なります。 (1)DrinkクラスでメソッドdispNameme()が定義されていないとき スーパークラスであるItemクラスで定義されているメソッドが使われます。 (2)DrinkクラスでメソッドdispNameme()が定義されているとき Drinkクラスで定義されているメソッドが使われます。 スーパークラスで定義されているメソッドと同じ名前のメソッドを サブクラスで再定義することもできます。 この場合サブクラスで定義したメソッドが優先されます。 これをメソッドのオーバーライドといいます。 どのクラスのメソッドが実行されるのか 1. インスタンスの属するクラスに対応するメソッドがあれば、それを実行する。 1. 無いときはスーパークラスの同じ名前のメソッドを探して、それを実行する。 1. 見つからないときは、親の親の親...と順に探します。 1. どうしても見つからないときはエラーになります。