010-001-004

消費税計算プログラム(メソッドのオーバーロード)

中級

問題説明

【解説】

🎯 問題の概要

この問題では、「メソッドのオーバーロード」という重要な概念を学びます。オーバーロードとは、同じ名前のメソッドを、引数の型や数を変えて複数定義する技術です。これにより、同じ処理を状況に応じて柔軟に呼び出せるようになります。

実務では、ユーザーが異なる形式でデータを渡してくる場合や、オプションパラメータがある場合などに、オーバーロードが頻繁に使われます。

📚 前提知識の確認

この問題を解くために必要な基礎知識:

  • メソッドの定義: 戻り値の型、メソッド名、引数リストの書き方
  • 引数の型: int、double、booleanなどの基本データ型
  • 算術演算: 乗算(*)、加算(+)、キャスト(型変換)
  • 条件分岐: if文、三項演算子(? :)

💡 解法のポイント

メソッドのオーバーロードを理解するための重要なポイント:

  1. メソッドのシグネチャ: Javaでは、メソッド名と引数リスト(型と個数)の組み合わせを「シグネチャ」と呼びます。シグネチャが異なれば、同じ名前のメソッドを複数定義できます。

  2. 自動的な選択: メソッド呼び出し時に、Javaコンパイラが引数の型と個数を見て、自動的に適切なメソッドを選びます。これにより、プログラマーは異なるメソッド名を覚える必要がありません。

  3. 実用的な利点: 同じ処理を異なる状況で使いたいとき、オーバーロードを使うことで、コードが読みやすく、使いやすくなります。例えば、calculate(価格)とcalculateWithCustomRate(価格, 税率)という別々の名前よりも、calculate(価格)とcalculate(価格, 税率)の方が直感的です。

📖 コード解説(ステップバイステップ)

ステップ1: クラスと定数の定義

public class TaxCalculator {
    private static final double DEFAULT_TAX_RATE = 10.0;
    private static final double DISCOUNT_RATE = 10.0;
```java
まず、クラスを定義し、プログラム全体で使う定数を設定します。税率や割引率を定数にすることで、後から変更しやすくなります。

### ステップ2: 1つ目のメソッド - デフォルト税率
```java
public int calculate(int price) {
    if (price < 0) {
        System.out.println("Error: Price must be positive");
        return -1;
    }
    return (int)(price * (1 + DEFAULT_TAX_RATE / 100));
}
```java
このメソッドは引数が1つ(価格のみ)です。税率は固定で10%を使用します。

計算式の説明:
- `DEFAULT_TAX_RATE / 100` で税率を小数に変換(10.0 → 0.1)
- `1 + 0.1 = 1.1` となり、これを価格に掛ける
- 1000円 × 1.1 = 1100円(税込み)

### ステップ3: 2つ目のメソッド - カスタム税率
```java
public int calculate(int price, double taxRate) {
    if (price < 0) {
        System.out.println("Error: Price must be positive");
        return -1;
    }
    if (taxRate < 0 || taxRate > 100) {
        System.out.println("Error: Tax rate must be between 0 and 100");
        return -1;
    }
    return (int)(price * (1 + taxRate / 100));
}
```java
このメソッドは引数が2つ(価格と税率)です。1つ目のメソッドと名前は同じですが、引数の個数が違うので別のメソッドとして認識されます。

### ステップ4: 3つ目のメソッド - 割引オプション
```java
public int calculate(int price, boolean includeDiscount) {
    if (price < 0) {
        System.out.println("Error: Price must be positive");
        return -1;
    }
    int discountedPrice = includeDiscount ? (int)(price * 0.9) : price;
    return (int)(discountedPrice * 1.10);
}
```java
このメソッドも引数が2つですが、2つ目の引数の型がboolean(真偽値)です。型が違うので、2つ目のメソッドとは別物として扱われます。

三項演算子の説明:
- `条件 ? 真の場合 : 偽の場合`
- `includeDiscount`がtrueなら価格の90%(10%オフ)、falseならそのままの価格

### ステップ5: メソッドの呼び出し
```java
calculator.calculate(1000);           // 引数1つ → 1つ目のメソッド
calculator.calculate(1000, 8.0);      // 引数2つ(int, double) → 2つ目のメソッド
calculator.calculate(1000, true);     // 引数2つ(int, boolean) → 3つ目のメソッド
```java
Javaコンパイラが引数の型と個数を見て、自動的に適切なメソッドを選んで実行します。

## ⚠️ よくある間違い

初学者が陥りやすいエラーパターン:

1. **戻り値の型だけ変えてオーバーロード**
   - 間違った例: 
   ```java
   public int calculate(int price) { ... }
   public double calculate(int price) { ... }  // ❌ エラー!
   ```java
   - 理由: 戻り値の型が違うだけでは、Javaはメソッドを区別できません。引数の型や個数が同じ場合、コンパイルエラーになります。
   - 正しい書き方: 引数の型か個数を変える
   ```java
   public int calculate(int price) { ... }
   public int calculate(int price, double taxRate) { ... }  // ✅ 正しい
   ```java

2. **引数名だけ変えてオーバーロード**
   - 間違った例:
   ```java
   public int calculate(int price) { ... }
   public int calculate(int amount) { ... }  // ❌ エラー!
   ```java
   - 理由: 引数名が違っても、型が同じなので区別できません。
   - 正しい書き方: 引数の型を変える
   ```java
   public int calculate(int price) { ... }
   public int calculate(double price) { ... }  // ✅ 正しい
   ```java

3. **キャストを忘れて小数が残る**
   - 間違った例:
   ```java
   return price * 1.10;  // ❌ double型が返される
   ```java
   - 理由: 1.10はdouble型なので、計算結果もdoubleになります。戻り値の型がintの場合、コンパイルエラーになります。
   - 正しい書き方:
   ```java
   return (int)(price * 1.10);  // ✅ キャストでintに変換
   ```java

## 🚀 発展的な内容

さらに学習を深めるためのヒント:

- **可変長引数**: `calculate(int... prices)`のように、任意の個数の引数を受け取るメソッドも定義できます。複数商品の合計税込み価格を計算する場合に便利です。

- **実務での応用**: データベース検索メソッドなどで、検索条件の数が状況によって違う場合、オーバーロードを使って柔軟に対応できます。例: `search(String name)`、`search(String name, int age)`、`search(String name, int age, String city)`

- **パフォーマンス最適化**: 引数の個数が少ないメソッドから、多いメソッドを呼び出す設計にすると、コードの重複を減らせます。例えば、`calculate(int price)`の中で`calculate(int price, double taxRate)`を呼び出し、デフォルト税率を渡すこともできます。

## 🔗 関連する学習項目

次に学ぶべきトピックやこの問題と関連する概念:

- **メソッドの戻り値**(カテゴリ009): メソッドから値を返す仕組みをより深く学びます
- **<a href="https://javadrill.tech/problems/011">コンストラクタ</a>のオーバーロード**(カテゴリ008): クラスの<a href="https://javadrill.tech/problems/011">コンストラクタ</a>もオーバーロードできます
- **可変長引数**(カテゴリ011): 引数の個数を自由に変えられる仕組みを学びます

テストケース例

※ 出力例はプログラミングの国際標準に準拠し英語で表示しています

入力:
期待される出力:
=== Sales Tax Calculator ===
----------------------------
Pattern 1 (Default 10%): 1100
Pattern 2 (Custom 8%): 1080
Pattern 3 (With Discount): 990
----------------------------
入力:
期待される出力:
=== Sales Tax Calculator ===
----------------------------
Pattern 1 (Default 10%): 1100
Pattern 2 (Custom 8%): 1080
Pattern 3 (With Discount): 990
----------------------------
入力:
期待される出力:
=== Sales Tax Calculator ===
----------------------------
Pattern 1 (Default 10%): 1100
Pattern 2 (Custom 8%): 1080
Pattern 3 (With Discount): 990
----------------------------
入力:
期待される出力:
=== Sales Tax Calculator ===
----------------------------
Pattern 1 (Default 10%): 1100
Pattern 2 (Custom 8%): 1080
Pattern 3 (With Discount): 990
----------------------------
入力:
期待される出力:
=== Sales Tax Calculator ===
----------------------------
Pattern 1 (Default 10%): 1100
Pattern 2 (Custom 8%): 1080
Pattern 3 (With Discount): 990
----------------------------
入力:
期待される出力:
=== Sales Tax Calculator ===
----------------------------
Pattern 1 (Default 10%): 1100
Pattern 2 (Custom 8%): 1080
Pattern 3 (With Discount): 990
----------------------------
入力:
期待される出力:
=== Sales Tax Calculator ===
----------------------------
Pattern 1 (Default 10%): 1100
Pattern 2 (Custom 8%): 1080
Pattern 3 (With Discount): 990
----------------------------
❌ テストに失敗したケースがあります
❌ エラー発生

あなたの解答

現在のモード: 自分のコード
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 回実行可能