Programming 3 / Java

トップに戻る

インスタンスメソッドとクラスメソッド

長方形の面積を求める2つの書き方を比べて、呼び出す対象、thisstatic の役割を理解します。

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
20000
2

インスタンスメソッド

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 = 20000
static メソッドには特定の呼び出し元インスタンスがないため、this は使えません。

なぜ width を直接使えないのか

次のコードでは、どの長方形の widthheight を使うのか決められないため、コンパイルエラーになります。

コンパイルエラーになる例
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.widthrectangle.width
「クラスメソッドはインスタンスに依存しない」とは、呼び出すためのインスタンスが不要という意味です。今回の計算結果は、引数で渡されたインスタンスの値に依存します。

今回、より自然なのはどちら?

長方形自身に「自分の面積を計算してもらう」と考えられるため、通常は smallRectangle.getArea() というインスタンスメソッドの書き方が自然です。

5

同じ名前を使える理由

2つのメソッドはどちらも getArea ですが、引数の構成が異なります。このように、同じ名前で引数が異なるメソッドを定義することをメソッドのオーバーロードと呼びます。

6

確認問題

  1. largeRectangle.getArea() を呼び出したとき、this は何を表しますか。
  2. Rectangle.getArea(smallRectangle) の仮引数 rectangle には何が入りますか。
  3. クラスメソッド内で this.width と書けないのはなぜですか。
解答を確認する
  1. largeRectangle を表します。
  2. smallRectangle への参照が入ります。
  3. クラスメソッドは特定のインスタンスから呼ばれず、this が存在しないためです。