== メソッド ==
クラスのもつ機能や動作、操作を定義したものをメソッドといいます。
メソッドはインスタンス(クラスのオブジェクト)に対する(オブジェクトを利用した)処理を記述したものとも言えます。
Itemクラスのメソッドを定義してみましょう。
. {{attachment:itemClass.png}}
前回作成したプログラムはこのようでした。
{{{#!java
public class Item
{
String name;
int price;
public static void main(String[] args)
{
Item a, b, c, d;
a = new Item();
a.name="りんご";
a.price=100;
b = new Item();
b.name="おにぎり";
b.price=120;
c = new Item();
c.name="お茶";
c.price=150;
System.out.printf("%s %d\n", a.name, a.price);
System.out.printf("%s %d\n", b.name, b.price);
System.out.printf("%s %d\n", c.name, c.price);
}
}
}}}
22~24行目に各変数の指しているオブジェクトの値を表示するためのprint文があります。
<
>この部分をメソッドを使って書き直します。
----
=== メソッドの定義 ===
Item.javaにshowという名前のメソッドを追加します。
showメソッドの定義は4行で書けます。
{{{#!java
void show()
{
System.out.printf("%s %d\n", this.name, this.price);
}
}}}
このメソッドは指定されたインスタンス内の変数の値を表示するものです。
<
>値を返さないので型はvoidです。
これを属性の定義の後ろ(5行目)に追加します。
----
=== メソッドの利用 ===
値を返さないメソッドの使い方は
'''インスタンス.メソッド();'''
です。
{{{
a.show();
}}}
のように、インスタンスとメソッド名をピリオドでつなぎ後ろに括弧を書きます。
void(値を返さない)型のメソッドの場合
インスタンスxxxに対してメソッドyyy()を行う
のように解釈すればよい。
この場合は「インスタンスaに対してshow()を行う」と読めます。
最初のプログラムでprint文で書いていたところをすべて、この形に書き直すとこのようになります。
{{{#!java
public class Item
{
String name;
int price;
void show()
{
System.out.printf("%s %d\n", this.name, this.price);
}
public static void main(String[] args)
{
Item a, b, c, d;
a = new Item();
a.name="りんご";
a.price=100;
b = new Item();
b.name="おにぎり";
b.price=120;
c = new Item();
c.name="お茶";
c.price=150;
a.show();
b.show();
c.show();
}
}
}}}
----
=== メソッドの動作 ===
メソッドが
インスタンス.メソッド();
として呼び出されると、このときのインスタンスの値が this に対応付けられてから、
メソッド本体が実行されます。
----
==== 例 ====
上のプログラムで変数a,b,cの値は次のようでした。(前回の解答参照)
. {{attachment:kekka2.png}}
すなわち
* aの値は,アドレス4a5ab2にあるItemクラスのインスタンス
* bの値は,アドレス1888759にあるItemクラスのインスタンス
* cの値は,アドレス6e1408にあるItemクラスのインスタンス
さて、27行目の
. a.show();
が実行されたときの動作を追ってみましょう。
1. aの値がthisに渡され
1. showの本体が実行される
aの値がthisに渡されると、thisの値は Item@4a5ab2 となり
aが指しているItemクラスのインスタンスをthisで参照できることになります。
showメソッドの本体では
this.nameとthis.priceの値を表示しています。
したがって
. a.show();
が行われると、
aが参照しているItemインスタンス内の変数の値が表示されます。
. {{attachment:itemObject.png}}
同様に、28行目の
. b.show();
ではbの値がthisに渡されて実行されるので、
bが参照しているItemインスタンス内の変数の値が表示されます。
----
=== 値を返すメソッド ===
値を返すメソッドは次のように記述します
. メソッド定義の先頭で返す型を指定
. メソッド本体ではreturn文を使って値を返す
{{{#!java
int getPrice()
{
return this.price;
}
}}}
. この例では値を返すことしかしていませんが、計算などの処理も行えます。
値を返すメソッドは計算式の中で使えます。
呼び出し方は同じです。
{{{
goukei = a.getPrice() + b.getPrice() + c.getPrice();
}}}
private属性の値を返すだけのメソッドはしばしば利用されます。
----
=== 値を修正するメソッド ===
メソッド内で、thisが指しているオブジェクト内の変数の値を修正することもできます。
例としてsetPriceメソッドを示します。
{{{#!java
void setPrice(int n)
{
this.price = n;
}
}}}
このメソッドは引数をとるので、呼び出し側でも引数の指定が必要です。
mainメソッド内で
{{{
b.setPrice(250);
}}}
を行うと、
bの指しているオブジェクト内の変数priceの値が250に修正されます。
private属性の値を修正するメソッドはしばしば利用されます。
-----
=== setPrice(), getPrice() ===
こんなメソッドを使わなくても、オブジェクト内の変数を直接参照すれば同じ処理が簡単に書けると思ったことでしょう。
小さなプログラムの場合はそれでかまいませんが、
大きなプログラムや堅牢性が要求される場合には、この形のメソッドが多用されます。
属性をprivateにしておき、
値の参照や修正をメソッドを使って行うようにすれば、
オブジェクトの状態をすべてクラス内で管理できるからです。
----
=== this ===
thisはキーワードです。
変数のように見えますが代入することはできません。
あいまいさが無いときは'''this.を省略'''することができます。
このページで示したメソッドではthis.がなくてもどの変数を指しているか明らかなので省略して
{{{#!java
void show()
{
System.out.printf("%s %d\n", name, price);
}
}}}
のように書けます。
thisを使って次のように書くこともしばしば行われます。
{{{
void setPrice(int price)
{
this.price = price;
}
}}}
priceという同じ名前がありますがthisを使うことで区別ができます。
. priceは引数
. this.priceはインスタンス内の変数