3秒でわかる
クラスの中で処理に名前を付け、受け取る引数と返す値の型を宣言すること。呼び出し側との約束を型として固定するための記述です。
もう少し詳しく
どういうものか
メソッド定義は、クラスの中で処理のまとまりに名前を付け、受け取る引数、返す値の型、公開範囲、投げうる例外を宣言する記述です。Java では、アクセス修飾子、戻り値型、メソッド名、引数リスト、本体という並びで書きます。呼び出し側が知るのは本体ではなく、この宣言部分だけです。
なぜ必要か
宣言部分は呼び出し側との契約になります。int を返すと書いてあれば、呼び出し側は null 判定を書く必要がありません。throws IOException と書いてあれば、失敗しうることが呼ぶ前に分かります。実装を書き換えても宣言が変わらない限り呼び出し側は影響を受けず、逆に宣言を変えれば影響範囲がコンパイルエラーとして機械的に列挙されます。
具体例
public class InventoryService {
public int reserve(String itemId, int quantity) throws OutOfStockException {
Item item = repository.find(itemId);
if (item.getStock() < quantity) {
throw new OutOfStockException(itemId);
}
item.decrease(quantity);
return item.getStock();
}
private void log(String message) { ... }
public int reserve(String itemId) throws OutOfStockException {
return reserve(itemId, 1); // オーバーロード
}
}同名で引数の並びが違うものを複数定義するのがオーバーロードで、親クラスの同じ宣言を子で書き換えるのがオーバーライドです。
つまずきやすいところ
@Override を付けておくとコンパイラが検出するtrue が何を指すのかが宣言側にしか無いpublic にすると、変更のたびに影響範囲が全体に広がる。既定は private から始める似た用語との違い
シグネチャはメソッド名と引数の並びだけを指し、戻り値型は含みません。宣言はシグネチャに戻り値型や例外を加えたもの、定義は本体まで含めたものと区別されます。
覚え方
宣言は看板、本体は厨房です。客が読むのは看板だけなので、看板を変えるときだけ全員に影響が出ます。