クラスにメソッドを定義する
このレッスンで分かること
- インスタンスメソッドは
インスタンス.メソッド名()の形で呼び出します、フィールドにthis.でアクセス- 静的メソッドは
クラス名.メソッド名()で呼ぶ、thisは使えない- 最小例は
class Book { String title, author; public String describe() { return this.title + " by " + this.author; } }
クラスにメソッドを定義する とは
クラスに振る舞いを持たせるインスタンスメソッドの定義方法と、static メソッドとの違いを学ぼう。本レッスンでは、クラスにメソッドを定義する の基本から実際の使いどころまでを整理し、現場で迷わず使える形に落とし込みます。
クラスにメソッドを定義する
前回までで、class を使ってデータ (フィールド) をひとまとめにし、new で インスタンス を作るところまで進みました。今回はそのクラスに 振る舞い を持たせる仕組み、インスタンスメソッド の書き方を学びます。データだけ持っていても料理は作れません。フィールドという「材料」に、メソッドという「調理手順」を組み合わせて、はじめてクラスは生きたオブジェクトになります。
オブジェクト指向では「オブジェクトはデータと振る舞いをひとまとめにしたもの」と説明されます。フィールドが
データ、メソッドが振る舞いの正体だと覚えてください。
インスタンスメソッドとは
インスタンスメソッド とは、new で作ったインスタンスごとに呼び出せるメソッドのことです。book.getDescription() のように、インスタンスの変数 . メソッド名() という形で呼び出します。同じクラスから作ったインスタンスでも、フィールドの値が違えば返ってくる結果が変わる、というのが大事なポイントです。
たとえば Book クラスに title と author というフィールドがあって、getDescription() メソッドがその 2 つを組み合わせた説明文を返すとしましょう。book1.getDescription() と book2.getDescription() は、同じメソッドを呼んでいるのに、book1 と book2 の中身に応じて違う文字列を返します。これが「振る舞いがインスタンスに紐づく」という意味です。
ここまで
Javaで書いてきたSolution.helloWorld()のような呼び方は静的メソッド(static method) と呼びます。クラスそのものに紐づくメソッドで、インスタンスを作らなくても呼べました。今回学ぶインスタンスメソッドはそれと対になる概念です。
インスタンスメソッドが活躍するのは次のような場面です。
- オブジェクトごとに違う情報を返したい —
book.getDescription()user.getFullName()product.getTaxIncludedPrice()などインスタンスのフィールドを使った計算 - オブジェクトの状態を変えたい —
counter.increment()cart.addItem(item)のように、内部の値を書き換える操作 - データと処理をまとめて扱いたい — フィールドとそれを操作するメソッドを 1 つのクラスに置くことで、関心ごとを 1 か所に集約できる
フィールドにアクセスする (this.field)
インスタンスメソッドの中では、this というキーワードを使って自分自身のフィールドにアクセスします。this.title と書けば「いま呼び出されているインスタンスの title」を指します。
Java
public class Book {
String title;
String author;
public String getDescription() {
return this.title + " by " + this.author;
}
}この Book クラスでは、フィールド title と author を this.title と this.author で参照しています。同じ名前のフィールドが複数のインスタンスに存在しても、this を介すことで「いま呼ばれた当人」の値を正しく取り出せます。
thisはメソッドの引数とフィールドの名前がぶつかったときに必須になります。引数と被らないときは省略してtitle + " by " + authorと書いても動きますが、初学者のうちはthis.を明示的に付けると「これはフィールド」と一目でわかって読みやすくなります。
呼び出し側のコードでは、new で Book を作って、title と author をセットしてから getDescription() を呼びます。
Java
public class Main {
public static void main(String[] args) {
Book book = new Book();
book.title = "Java 入門";
book.author = "著者A";
String desc = book.getDescription();
System.out.println(desc);
}
}出力は Java 入門 by 著者A です。getDescription() の中で this.title this.author がそれぞれ "Java 入門" "著者A" に置き換わって連結されています。
メソッドはオブジェクトの「振る舞い」を表現する
インスタンスメソッドの本質は「そのオブジェクトが何をできるか」を表現することです。Book というオブジェクトは「自己紹介できる」(getDescription())、Counter というオブジェクトは「カウントアップできる」(increment())、Cart というオブジェクトは「商品を追加できる」(addItem()) というふうに、メソッド名はそのまま「動詞 + 名詞」でクラスの能力を物語ります。
設計のコツは、メソッド名を見たら何をするかが想像できる名前にすること、そして 1 つのメソッドに詰め込みすぎないことです。doEverything() のような巨大メソッドは保守が大変なので、calculatePrice() formatLabel() のように責任を分けるのが基本です。
メソッドが呼ばれた瞬間の流れを図で見てみましょう。呼び出し元から book.getDescription() を実行すると、いったん主役が Book インスタンスの内部に移り、this.title と this.author を組み立てて、return で呼び出し元に戻ってきます。
この「呼び出し元 → インスタンス → 呼び出し元」というキャッチボールこそが、オブジェクト指向の世界でのメソッド呼び出しのリズムです。
静的メソッドとの違い
静的メソッド (static) とインスタンスメソッド (static なし) の違いは、次のとおりです。
- 静的メソッド —
クラス名.メソッド名()で呼ぶ。インスタンスを作らなくても呼べる。thisは使えない - インスタンスメソッド —
インスタンス変数.メソッド名()で呼ぶ。先にnewでインスタンスを作る必要がある。thisで自分のフィールドにアクセスできる
| 観点 | 静的メソッド (static) | インスタンスメソッド |
|---|---|---|
| 呼び出し | クラス名.メソッド名() | インスタンス.メソッド名() |
| 事前準備 | 不要 | new でインスタンスを作る必要あり |
this | 使えない | 使える (自分自身を指す) |
| フィールドへのアクセス | static フィールドのみ | インスタンスのフィールド可 |
| 代表例 | Math.max(1, 2) | book.getDescription() |
Math.max(1, 2) のような「ただの計算を呼びたい」場面は静的メソッド向き、book.getDescription() のように「自分のフィールドを使って答えたい」場面はインスタンスメソッド向き、と覚えると判断しやすくなります。
同じクラスの中に、静的メソッドとインスタンスメソッドを両方置くこともできます。
mainメソッドは典型的なstaticメソッドで、その中からnew Book()でインスタンスを作ってbook.getDescription()を呼び出す、という組み合わせが定番です。
両者の関係を頭の中で整理しておきましょう。
Java
public class Demo {
String name;
// インスタンスメソッド: this が使える
public String greetInstance() {
return "Hello, " + this.name;
}
// 静的メソッド: this は使えない
public static String greetStatic(String who) {
return "Hello, " + who;
}
}Demo.greetStatic("Java") はそのまま呼べますが、Demo.greetInstance() という書き方はできません。Demo d = new Demo(); d.name = "Java"; d.greetInstance(); のように、先にインスタンスを用意する必要があります。
よくある間違い
インスタンスメソッドを書き始めた頃に、ほぼ全員がぶつかる落とし穴を 3 つ紹介します。
staticを付けたり外したりを間違える — クラス内のフィールドを使うインスタンスメソッドにstaticを付けると、non-static field cannot be referenced from a static contextというエラーが出ます。逆にユーティリティ的な計算なのにstaticを外すと、毎回newしてから呼ばないといけなくなり不便です。「フィールドに触るかどうか」で判断しましょうthisを使わずに引数とフィールドを混同する — メソッドの引数とフィールドが同じ名前のとき、title = title;と書いても何も起きません (引数が引数に代入されているだけ)。this.title = title;のように、フィールド側だけthis.を付けて区別する必要があります- 戻り値の型と
returnの値がずれる — メソッドの宣言がpublic String getDescription()なのにreturn 123;と書くとコンパイルエラーです。戻り値の型とreturnで返す値の型は必ず一致させてください。何も返さないなら戻り値型をvoidに変える、というルールも忘れずに
エラーメッセージは敵ではなく味方です。
cannot find symbolならタイポ、non-static fieldならstaticの付けすぎ、incompatible typesなら型の不一致、と見分けがつくと修正がぐっと早くなります。
ここまでの要点
インスタンスメソッドは new 必須、this.field で自分のフィールドに触れる。static メソッドは this が使えず、フィールドに触らない計算向き。フィールドに触るかどうかで使い分ける。
やってみよう
それでは課題に挑戦しましょう。今回は本文で紹介した Book クラスに インスタンスメソッド を 1 つ実装し、そのメソッドを呼んだ結果を返します。手順は次のとおりです。
- 右側のエディタを開く
Solutionの中のstatic class Bookを確認する (フィールドtitleauthorとコンストラクタが用意されている)Bookクラスのdescribe()メソッドにreturn this.title + " by " + this.author;を書くbookDescription(title, author)の中でreturn new Book(title, author).describe();のように、インスタンスを作ってdescribe()を呼ぶ- 「実行」ボタンを押して、テストが緑になることを確認する
固定で return "Java 入門 by 著者A"; と書くと 1 ケース目だけは通りますが、それ以外のテストケースで fail します。インスタンスメソッドを実際に経由しないとパスできない作り になっているので、必ず new Book(...).describe() の形で書いてください。
by の前後には半角スペースが 1 つずつ入ります。スペースの有無や全角・半角の違いでテストが落ちるので注意しましょう。
クラスとメソッドが組み合わさると、Java プログラムの表現力は一気に広がります。ここから先は コンストラクタ、カプセル化、継承 と、オブジェクト指向の世界がさらに深まっていきます。まずはこのレッスンで、データと振る舞いを 1 つのクラスにまとめる気持ちよさを体験してみましょう。
よくある質問
Q. メソッドの引数は何個まで書けますか?
A. 言語的には何個でも書けますが、4-5 個を超えると呼び出し側が読みにくくなります。多くなったら関連する引数をクラスや record(Java)/ dataclass(Python)/ オブジェクト(JS)にまとめ、1 つの引数として渡すのがリファクタの定石です。
Q. 戻り値の型 void と他の型はどう使い分けますか?
A. 副作用(DB 更新、画面描画)だけならvoid、計算結果や状態を返すなら具体的な型です。テストしやすさは戻り値ありの方が圧倒的に高いため、純粋関数として書けるところはなるべく値を返す設計にすると良いです。
Q. static メソッドはいつ使いますか?
A. インスタンスの状態に依存しないユーティリティ関数(Math.max など)に向きます。逆にフィールドを使うなら static にせず、インスタンスメソッドにしてください。テスト時に static は差し替えにくいため、依存注入したいなら避けるのが無難です。
次のレッスン
次は インスタンスを作る で、クラスに振る舞いを持たせるインスタンスメソッドの定義方法と、static メソッドとの違いを学ぼう を学びます。
事前確認 — 進む前に次の 3 つができることを確認しましょう。
- クラスメソッド の要点を自分の言葉で説明できる
- このレッスンの最小コード (または操作手順) を見ずに書ける
- 練習問題やクイズで間違えた箇所を読み直して理解した
理解度チェック (30 秒)
Q. クラスメソッド とは何か、1 文で説明してください。
A. 本文の「このレッスンで分かること」または冒頭の説明文を見直し、自分の言葉で要約できれば OK。詰まったら本レッスンの最初の H2 セクションを読み返してみましょう。
関連レッスン
要件
Bookクラスのインスタンスメソッドdescribe()を実装することbookDescriptionの中でnew Book(title, author).describe()のようにインスタンスメソッドを呼ぶこと (固定文字列の即時 return は不可)describe()は"<title> by <author>"の形 (半角スペース付き) の文字列を返すこと
入出力例
test-cases.txt
bookDescription("Java 入門", "著者A") → "Java 入門 by 著者A"
bookDescription("Effective Java", "Joshua") → "Effective Java by Joshua"
bookDescription("確認", "チーム") → "確認 by チーム"