008-001-002
メソッドの定義: レシピ材料費計算プログラム
中級
問題説明
【解説】
1. 問題の背景と目的
この問題では、料理のレシピに必要な材料の費用を計算するプログラムを通じて、メソッドの定義と呼び出しの基本を学びます。メソッドは、処理をまとめて名前を付けたもので、同じ計算を何度も書く代わりに、一度定義すれば何度でも再利用できます。実務では、コードの重複を避け、保守性を高めるために必須のスキルです。
この学習は、次のステップである「複数のメソッドを組み合わせる」「メソッドのオーバーロード」「クラス設計」へと繋がる重要な基礎となります。
2. 前提知識の詳細説明
この問題を解くために必要な知識は以下の通りです:
メソッドとは
メソッドは、特定の処理をまとめたものです。例えば「価格×数量」という計算を何度も書く代わりに、calculateCostというメソッドとして定義しておけば、必要なときに呼び出すだけで済みます。
引数(パラメータ)
引数は、メソッドに渡す値のことです。今回のcalculateCostメソッドでは、price(価格)とquantity(数量)という2つの引数を受け取ります。メソッドを呼び出すとき、実際の値(例: 150, 2)を渡します。
戻り値(返り値)
戻り値は、メソッドが計算した結果を呼び出し元に返す値です。calculateCostメソッドは、価格×数量の計算結果(小計)をint型で返します。
static キーワード
staticは「静的」という意味で、インスタンスを作らなくてもメソッドを呼び出せるようにします。mainメソッドから直接呼び出すメソッドにはstaticが必要です。
3. コードの行ごとの詳細解説
メソッドの定義部分
public static int calculateCost(int price, int quantity) {
return price * quantity;
}
```java
- `public`: どこからでもアクセス可能(アクセス修飾子)
- `static`: インスタンス化なしで呼び出し可能
- `int`: 戻り値の型(整数を返す)
- `calculateCost`: メソッド名(何をするメソッドかが分かる名前)
- `(int price, int quantity)`: 引数リスト(価格と数量を受け取る)
- `return price * quantity;`: 計算結果を返す(戻り値)
### mainメソッド内でのメソッド呼び出し
```java
int subtotal1 = calculateCost(price1, quantity1);
```java
この行では、以下のことが起きています:
1. `calculateCost`メソッドを呼び出す
2. `price1`と`quantity1`の値を引数として渡す(例: 150, 2)
3. メソッド内で `150 * 2 = 300` が計算される
4. 計算結果(300)が戻り値として返される
5. 戻り値が<a href="https://javadrill.tech/problems/001">変数</a>`subtotal1`に代入される
このようにして、同じメソッドを異なる引数で2回呼び出すことで、2つの材料の小計を計算しています。
### 出力部分
```java
System.out.println("Item 1: " + price1 + " x " + quantity1 + " = " + subtotal1);
```java
この行では、文字列結合(+<a href="https://javadrill.tech/problems/003">演算子</a>)を使って、視覚的に分かりやすい形式で出力しています。例えば、price1が150、quantity1が2、subtotal1が300の場合、以下のように表示されます:
```java
Item 1: 150 x 2 = 300
```java
このような視覚的なフィードバックは、プログラムの動作を理解しやすくし、学習効果を高めます。
## 4. よくある間違いと修正例
### 間違い1: メソッドの戻り値の型を忘れる
```java
// ❌ 間違い
public static calculateCost(int price, int quantity) {
return price * quantity;
}
// ✅ 正しい
public static int calculateCost(int price, int quantity) {
return price * quantity;
}
```java
**理由**: Javaでは、メソッドが何型の値を返すかを明示する必要があります。今回は整数(int)を返すので、`int`と書きます。
### 間違い2: returnを忘れる
```java
// ❌ 間違い
public static int calculateCost(int price, int quantity) {
int result = price * quantity;
// returnがない!
}
// ✅ 正しい
public static int calculateCost(int price, int quantity) {
return price * quantity;
}
```java
**理由**: 戻り値の型が`int`と宣言されている場合、必ず`return`文で値を返す必要があります。returnがないとコンパイルエラーになります。
### 間違い3: staticを忘れる
```java
// ❌ 間違い
public int calculateCost(int price, int quantity) {
return price * quantity;
}
// ✅ 正しい
public static int calculateCost(int price, int quantity) {
return price * quantity;
}
```java
**理由**: `main`メソッドは`static`なので、そこから呼び出すメソッドも`static`である必要があります。`static`がないと、インスタンスを作成する必要があり、初心者には複雑すぎます。
## 5. 実践的なデバッグのヒント
### メソッドの動作確認
メソッドが正しく動いているか確認するには、以下のようにデバッグ出力を追加します:
```java
public static int calculateCost(int price, int quantity) {
int result = price * quantity;
System.out.println("Debug: " + price + " x " + quantity + " = " + result);
return result;
}
```java
これにより、メソッドが呼び出されるたびに、どのような計算が行われているかが確認できます。
### よく見るエラーメッセージ
1. **「non-static method cannot be referenced from a static context」**
- 原因: メソッドに`static`がない
- 解決: メソッド定義に`static`を追加
2. **「missing return statement」**
- 原因: `return`文がない、または条件によっては実行されない
- 解決: すべてのパスで`return`文が実行されるようにする
3. **「incompatible types」**
- 原因: 戻り値の型と実際の返す値の型が一致しない
- 解決: 戻り値の型を確認し、正しい型の値を返す
## 6. 発展的な内容
### より実用的なメソッド設計
実務では、以下のような改良を加えることがあります:
```java
// 消費税を含めた金額を計算するメソッド
public static int calculateCostWithTax(int price, int quantity, double taxRate) {
int subtotal = price * quantity;
return (int)(subtotal * (1 + taxRate));
}
```java
このように、メソッドを組み合わせたり、引数を増やしたりすることで、より複雑な計算を扱えるようになります。
### パフォーマンス最適化
今回のような単純な計算では不要ですが、複雑な計算の場合、メソッド内で計算結果をキャッシュするなどの最適化が考えられます。
### エラーハンドリング
より堅牢なプログラムにするには、以下のような検証を追加します:
```java
public static int calculateCost(int price, int quantity) {
if (price < 0 || quantity < 0) {
System.out.println("Error: Negative values not allowed");
return 0;
}
return price * quantity;
}
```java
## 7. 関連する学習項目
次に学ぶべきトピックや、この問題と関連する概念:
- **メソッドのオーバーロード**(カテゴリ008-002): 同じ名前で引数の異なるメソッドを定義する
- **再帰メソッド**(カテゴリ008-003): メソッドが自分自身を呼び出す
- **<a href="https://javadrill.tech/problems/007">クラス</a>とインスタンスメソッド**(カテゴリ009-001): `static`でないメソッドの使い方
- **<a href="https://javadrill.tech/problems/004">配列</a>を引数に取るメソッド**(カテゴリ010-002): より複雑なデータをメソッドで処理する
メソッドの基本をしっかり理解することで、これらの発展的なトピックがスムーズに学べるようになります。
テストケース例
※ 出力例はプログラミングの国際標準に準拠し英語で表示しています
入力:
150 2 200 3
期待される出力:
Item 1: 150 x 2 = 300 Item 2: 200 x 3 = 600 --- Total: 900
入力:
100 5 250 2
期待される出力:
Item 1: 100 x 5 = 500 Item 2: 250 x 2 = 500 --- Total: 1000
入力:
1 1 1 1
期待される出力:
Item 1: 1 x 1 = 1 Item 2: 1 x 1 = 1 --- Total: 2
入力:
1000 10 500 20
期待される出力:
Item 1: 1000 x 10 = 10000 Item 2: 500 x 20 = 10000 --- Total: 20000
入力:
0 5 100 2
期待される出力:
Item 1: 0 x 5 = 0 Item 2: 100 x 2 = 200 --- Total: 200
入力:
100 0 200 0
期待される出力:
Item 1: 100 x 0 = 0 Item 2: 200 x 0 = 0 --- Total: 0
❌ テストに失敗したケースがあります
あなたの解答
現在のモード:● 自分のコード
99
1
2
3
4
5
6
7
8
9
10
›
⌄
⌄
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
// ここにコードを書いてください
sc.close();
}
}
0 B / 5 MB
残り 8 回実行可能
