1
2種類の面積計算
同じ長方形の面積を、インスタンスメソッドとクラスメソッドの両方で計算します。まずコード全体と出力を確認しましょう。
Rectangle.java
public class Rectangle {
int width;
int height;
Rectangle(int width, int height) {
this.width = width;
this.height = height;
}
// インスタンスメソッド
int getArea() {
return width * height;
}
// クラスメソッド
static int getArea(Rectangle rectangle) {
return rectangle.width * rectangle.height;
}
public static void main(String[] args) {
Rectangle smallRectangle = new Rectangle(10, 20);
Rectangle largeRectangle = new Rectangle(100, 200);
System.out.println(smallRectangle.getArea());
System.out.println(largeRectangle.getArea());
System.out.println(Rectangle.getArea(smallRectangle));
System.out.println(Rectangle.getArea(largeRectangle));
}
}
実行結果を確認する
output
200
20000
200
200002
インスタンスメソッド
smallRectangle.getArea() のように、処理をしてほしいインスタンスから呼び出します。メソッド内では、そのインスタンスを this で表せます。
呼び出す
→
smallRectangle.getArea()this が決まる
→
this = smallRectangle計算する
10 × 20 = 200省略された this
int getArea() {
return this.width * this.height;
}width とだけ書いた場合も、このメソッドでは this.width と同じ意味です。
3
クラスメソッド
static が付いたクラスメソッドは、Rectangle.getArea(...) のようにクラス名から呼び出します。計算対象は引数で受け取ります。
呼び出す
→
Rectangle.getArea(largeRectangle)引数を渡す
→
rectangle = largeRectangle計算する
100 × 200 = 20000static メソッドには特定の呼び出し元インスタンスがないため、this は使えません。
なぜ width を直接使えないのか
次のコードでは、どの長方形の width と height を使うのか決められないため、コンパイルエラーになります。
コンパイルエラーになる例
static int getArea(Rectangle rectangle) {
return width * height; // 対象が分からない
}rectangle.width のように、引数として渡された対象を明示すれば計算できます。
4
2つの違いを整理
| 項目 | インスタンスメソッド | クラスメソッド |
|---|---|---|
| 定義 | int getArea() | static int getArea(Rectangle r) |
| 呼び出し | smallRectangle.getArea() | Rectangle.getArea(largeRectangle) |
| 計算対象 | 呼び出し元のインスタンス | 引数で渡したインスタンス |
this | 使用できる | 使用できない |
| フィールド参照 | width または this.width | rectangle.width |
「クラスメソッドはインスタンスに依存しない」とは、呼び出すためのインスタンスが不要という意味です。今回の計算結果は、引数で渡されたインスタンスの値に依存します。
今回、より自然なのはどちら?
長方形自身に「自分の面積を計算してもらう」と考えられるため、通常は smallRectangle.getArea() というインスタンスメソッドの書き方が自然です。
5
同じ名前を使える理由
2つのメソッドはどちらも getArea ですが、引数の構成が異なります。このように、同じ名前で引数が異なるメソッドを定義することをメソッドのオーバーロードと呼びます。
- getArea()引数なし。インスタンスメソッドが選ばれる。
- getArea(Rectangle)Rectangle型の引数が1つ。クラスメソッドが選ばれる。
- Javaの判断メソッド名だけでなく、引数の個数や型を見て選ぶ。
6
確認問題
- largeRectangle.getArea() を呼び出したとき、this は何を表しますか。
- Rectangle.getArea(smallRectangle) の仮引数 rectangle には何が入りますか。
- クラスメソッド内で this.width と書けないのはなぜですか。
解答を確認する
- largeRectangle を表します。
- smallRectangle への参照が入ります。
- クラスメソッドは特定のインスタンスから呼ばれず、this が存在しないためです。