Sales Tax Calculator (Method Overloading)
Problem Description
[Explanation]
🎯 Problem Overview
This problem teaches you about the important concept of "method overloading". Overloading is a technique where you define multiple methods with the same name but different parameter types or counts. This allows you to call the same operation flexibly depending on the situation.
In real-world development, overloading is frequently used when users pass data in different formats or when there are optional parameters.
📥 Input Format
Read the following 2 lines from standard input:
- Line 1: Product price (positive integer)
- Line 2: Custom tax rate (decimal between 0 and 100)
Input example:
1000
8.0
Output example:
=== Sales Tax Calculator ===
----------------------------
Pattern 1 (Default 10%): 1100
Pattern 2 (Custom 8%): 1080
Pattern 3 (With Discount): 990
----------------------------
📚 Prerequisites
Knowledge required to solve this problem:
- method definition: How to write return type, method name, and parameter list
- Parameter types: Basic data types like int, double, boolean
- Arithmetic operations: Multiplication (*), addition (+), casting (type conversion)
- conditional branching: if statements, ternary operator (? :)
- Scanner: Reading values from standard input
💡 Key Points
Important points to understand method overloading:
method signature: In Java, the combination of method name and parameter list (types and count) is called a "signature". If signatures differ, you can define multiple methods with the same name.
Automatic selection: When calling a method, the Java compiler automatically selects the appropriate method by looking at the argument types and count. This means programmers don't need to remember different method names.
Practical advantages: When you want to use the same operation in different situations, overloading makes code more readable and user-friendly. For example, calculate(price) and calculate(price, taxRate) is more intuitive than separate names like calculate(price) and calculateWithCustomRate(price, taxRate).
📖 Code Explanation (Step by Step)
Step 1: class and constant definition
public class TaxCalculator {
private static final double DEFAULT_TAX_RATE = 10.0;
private static final double DISCOUNT_RATE = 10.0;
```java
First, define the class and set constants used throughout the program. Making tax rate and discount rate constants makes them easier to change later.
### Step 2: First method - Default tax rate
```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
This method has one parameter (price only). Tax rate is fixed at 10%.
Calculation explanation:
- `DEFAULT_TAX_RATE / 100` converts tax rate to decimal (10.0 → 0.1)
- `1 + 0.1 = 1.1`, multiply this by price
- 1000 yen × 1.1 = 1100 yen (including tax)
### Step 3: Second method - Custom tax rate
```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
This method has two parameters (price and tax rate). Same name as first method, but different parameter count, so it's recognized as a different method.
### Step 4: Third method - Discount option
```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
This method also has two parameters, but the second parameter type is boolean. Different type, so treated as separate from the second method.
Ternary operator explanation:
- `condition ? Value_if_true : value_if_false`
- If `includeDiscount` is true, 90% of price (10% off), otherwise original price
### Step 5: Reading input and calling methods
```java
Scanner scanner = new Scanner(System.in);
int price = scanner.nextInt(); // Line 1: product price
double taxRate = scanner.nextDouble(); // Line 2: custom tax rate
scanner.close();
calculator.calculate(price); // 1 argument → first method
calculator.calculate(price, taxRate); // 2 arguments (int, double) → second method
calculator.calculate(price, true); // 2 arguments (int, boolean) → third method
```java
Java compiler looks at argument types and count, automatically selecting and executing the appropriate method.
## ⚠️ Common Mistakes
Error patterns beginners often fall into:
1. **Overloading with only return type difference**
- Wrong example:
```java
public int calculate(int price) { ... }
public double calculate(int price) { ... } // ❌ Error!
```java
- Reason: Java cannot distinguish methods by return type alone. If parameter types and count are the same, you'll get a compile error.
- Correct approach: Change parameter type or count
```java
public int calculate(int price) { ... }
public int calculate(int price, double taxRate) { ... } // ✅ Correct
```java
2. **Overloading with only parameter name difference**
- Wrong example:
```java
public int calculate(int price) { ... }
public int calculate(int amount) { ... } // ❌ Error!
```java
- Reason: Different parameter names but same type, so cannot be distinguished.
- Correct approach: Change parameter type
```java
public int calculate(int price) { ... }
public int calculate(double price) { ... } // ✅ Correct
```java
3. **Forgetting <a href="https://javadrill.tech/problems/003/006">cast</a>, leaving decimal**
- Wrong example:
```java
return price * 1.10; // ❌ Returns double type
```java
- Reason: 1.10 is double type, so calculation result is also double. If return type is int, you'll get a compile error.
- Correct approach:
```java
return (int)(price * 1.10); // ✅ Cast to int
```java
## 🚀 Advanced Topics
Hints for deeper learning:
- **Varargs**: You can define methods that accept arbitrary number of arguments like `calculate(int... Prices)`. Useful for calculating total tax-included price of multiple products.
- **Real-world application**: In database search methods where the number of search conditions varies by situation, you can use overloading for flexible handling. Example: `search(String name)`, `search(String name, int age)`, `search(String name, int age, String city)`
- **Performance optimization**: Designing so that methods with fewer parameters call methods with more parameters reduces code duplication. For example, `calculate(int price)` can call `calculate(int price, double taxRate)` internally and pass the default tax rate.
## 🔗 Related Learning Topics
Topics to learn next or concepts related to this problem:
- **Method return values** (Category 009): Learn more deeply about the mechanism of returning values from methods
- **<a href="https://javadrill.tech/problems/011">constructor</a> overloading** (Category 008): Class constructors can also be overloaded
- **Varargs** (Category 011): Learn about the mechanism to freely change the number of arguments.
Ready to Try Running Code?
Log in to access the code editor and execute your solutions for this problem.
Don't have an account?
Sign Up