F-lab Java 1์ฃผ์ฐจ / Phase 2 / Unit 2.1 ๋ณธ๊ฒฉ ํ์ต ์๋ฃ
9-์น์ ๋ง์คํฐ ํ๋กฌํํธ ํ์์ผ๋ก ๊น์ด ํํค์น๋ค.์ ์ ์ง์: Unit 1.2 (ํด๋์ค์ ๊ฐ์ฒด์ ๋ณธ์ง)
๋ค์ Unit: 2.2 โ ๊ฐ๋ณ์ธ์ (Varargs)
์ ์๋ ์ธ์ง๋ฅผ ๋ ์ฌ๋ ค๋ณด์ธ์. ์ ์๋ ์ธ์ง์๋ ๋ค์ํ ๋ฒํผ์ด ์์ต๋๋ค:
๊ฐ ๋ฒํผ์ ์ธ ๊ฐ์ง ์ ๋ณด๋ฅผ ๊ฐ์ง๋๋ค:
โ ์ด๊ฒ ๋ฉ์๋์ ๋ณธ์ง์ ๋๋ค. ๊ฐ์ฒด๊ฐ ๊ฐ์ง "๋ฒํผ" ๋ค์ด ๋ฉ์๋.
ATM์ ๋ฉ๋ด๋ฅผ ๋ณด๋ฉด:
| ATM ๋ฒํผ | ์ ๋ ฅ | ๊ฒฐ๊ณผ |
|---|---|---|
| "์์ก ์กฐํ" | ๋น๋ฐ๋ฒํธ | ์์ก |
| "์ถ๊ธ" | ๋น๋ฐ๋ฒํธ, ๊ธ์ก | ํ๊ธ + ์์์ฆ |
| "์ ๊ธ" | ํ๊ธ | ์์์ฆ |
| "ํ๋ฉด ์ข ๋ฃ" | ์์ | ์์ |
๊ฐ ๋ฒํผ์ด ๋ฉ์๋, ATM์ด ๊ฐ์ฒด ์ ๋๋ค.
๋น์ ์ ATM์ ๋ด๋ถ ๋์(๋ฐ์ดํฐ๋ฒ ์ด์ค ์กฐํ, ์นด๋ ์ธ์ฆ, ํ๊ธ ์นด์ดํฐ ์๋...) ์ ๋ชฐ๋ผ๋, ๋ฒํผ๋ง ๋๋ฅด๋ฉด ๋ฉ๋๋ค.
โ ๋ฉ์๋๋ ๊ฐ์ฒด์๊ฒ ์ผ์ ์ํค๋ ๋ช ๋ น ์ฐฝ๊ตฌ.
| ๋น์ ์์ | ์๋ฐ ๋ฉ์๋ |
|---|---|
| ๋ฒํผ ์ด๋ฆ | ๋ฉ์๋๋ช |
| ๋ฒํผ ์ ๋ ฅ | ๋งค๊ฐ๋ณ์ |
| ๋ฒํผ ๊ฒฐ๊ณผ | ๋ฐํ๊ฐ |
| ๋ฒํผ ๋๋ฅด๋ ํ์ | ๋ฉ์๋ ํธ์ถ |
| ๋๊ฐ ๋๋ฅผ ์ ์๋ | ์ ๊ทผ ์ ์ด์ |
์ด๊ธฐ ํ๋ก๊ทธ๋๋ฐ (์ด์ ๋ธ๋ฆฌ, ์ด๊ธฐ BASIC) ์์๋ ํจ์(๋ฉ์๋) ๋ผ๋ ๊ฐ๋ ์ด ์๊ฑฐ๋ ์ฝํ์ต๋๋ค.
๊ฐ์ ์์ ์ ๋ฐ๋ณตํ๋ ค๋ฉด:
[ํ๋ก๊ทธ๋จ]
์ฃผ๋ฌธ 1๋ฒ ์ฒ๋ฆฌ:
- ๊ฐ๊ฒฉ ๊ณ์ฐ ์ฝ๋ 100์ค
- ์ธ๊ธ ๊ณ์ฐ ์ฝ๋ 50์ค
- ๊ฒฐ์ ์ฝ๋ 80์ค
์ฃผ๋ฌธ 2๋ฒ ์ฒ๋ฆฌ:
- ๊ฐ๊ฒฉ ๊ณ์ฐ ์ฝ๋ 100์ค โ ๋๊ฐ์ ์ฝ๋ ๋ ์์ฑ
- ์ธ๊ธ ๊ณ์ฐ ์ฝ๋ 50์ค โ ๋ ์์ฑ
- ๊ฒฐ์ ์ฝ๋ 80์ค โ ๋ ์์ฑ
์ฃผ๋ฌธ 3๋ฒ ์ฒ๋ฆฌ:
- ... ๋ ๋๊ฐ์ด ...
๋ฌธ์ :
์ด ๋ฌธ์ ๋ฅผ ํด๊ฒฐํ๋ ค๊ณ "ํจ์" ๊ฐ ๋ฑ์ฅ:
ํจ์ ์ ์: ๊ฐ๊ฒฉ_๊ณ์ฐํ๊ธฐ = (...์ฝ๋ 100์ค...)
[ํ๋ก๊ทธ๋จ]
์ฃผ๋ฌธ 1๋ฒ ์ฒ๋ฆฌ:
- ๊ฐ๊ฒฉ_๊ณ์ฐํ๊ธฐ() ํธ์ถ
- ์ธ๊ธ_๊ณ์ฐํ๊ธฐ() ํธ์ถ
- ๊ฒฐ์ ํ๊ธฐ() ํธ์ถ
์ฃผ๋ฌธ 2๋ฒ ์ฒ๋ฆฌ:
- ๊ฐ๊ฒฉ_๊ณ์ฐํ๊ธฐ() โ ๊ฐ์ ํจ์ ์ฌ์ฌ์ฉ
- ์ธ๊ธ_๊ณ์ฐํ๊ธฐ()
- ๊ฒฐ์ ํ๊ธฐ()
ํจ๊ณผ:
โ ํจ์๋ "์ฌ์ฌ์ฉ ๊ฐ๋ฅํ ์ฝ๋ ๋จ์" ๋ผ๋ ํ๋ช ์ ๋ฐ๋ช .
์๋ฐ ๊ฐ์ ๊ฐ์ฒด์งํฅ ์ธ์ด์์๋ ํจ์๊ฐ ๊ฐ์ฒด์ ๋ฌถ์ด๋ฉด์ ์ด๋ฆ์ด ๋ฉ์๋(method) ๋ก ๋ฐ๋๋๋ค.
| ํจ์ (Function) | ๋ฉ์๋ (Method) | |
|---|---|---|
| ์์ | ๋ ๋ฆฝ์ (์ ์ญ) | ํด๋์ค์ ์ํจ |
| ํธ์ถ | ํจ์๋ช
() | ๊ฐ์ฒด.๋ฉ์๋๋ช
() |
| ๋ฐ์ดํฐ ์ ๊ทผ | ์ธ์๋ก ๋ฐ์ | ์๊ธฐ ๊ฐ์ฒด์ ํ๋ ์ง์ ์ ๊ทผ |
| ์ | C์ printf() | ์๋ฐ์ obj.toString() |
โ ๋ฉ์๋๋ "๊ฐ์ฒด์ ํ๋์ ์ ์ํ๋ ํจ์".
"๋ฉ์๋๋ ๊ฐ์ฒด๊ฐ ํ ์ ์๋ ์ผ์ ์ ์ํ ์ฝ์์ด๋ค."
๊ฐ์ฒด์๊ฒ ๋ฉ์๋๋:
๊ฐ์ฒด๊ฐ ๋ฐ์ดํฐ(ํ๋)๋ง ์๊ณ ๋ฉ์๋๊ฐ ์๋ค๋ฉด ์ด๋ค ์ผ์ด ๋ฒ์ด์ง๊น์?
// ๋ฉ์๋ ์๋ ๋นํ ๊ฐ์ฒด โ
public class BankAccount {
public int balance; // ์์ก (public์ด ๋ฌธ์ ๋ ํค์)
}
์ด ๊ฐ์ฒด๋ฅผ ์ฌ์ฉํ๋ ค๋ฉด ์ธ๋ถ์์ ๋ชจ๋ ์ผ์ ์ง์ ํด์ผ ํฉ๋๋ค:
BankAccount account = new BankAccount();
account.balance = 10000;
// ์
๊ธํ๋ ค๋ฉด?
account.balance = account.balance + 5000; // ์ธ๋ถ์์ ์ง์ ๊ณ์ฐ
// ์ถ๊ธํ๋ ค๋ฉด?
if (account.balance >= 3000) {
account.balance = account.balance - 3000; // ์ธ๋ถ์์ ๊ฒ์ฆ + ๊ณ์ฐ
} else {
System.out.println("์์ก ๋ถ์กฑ");
}
// ๋ค๋ฅธ ๊ณณ์์๋ ๊ฐ์ ์
๊ธ/์ถ๊ธ์ด ํ์ํ ๋?
// โ ๊ฐ์ ์ฝ๋ ๋ ์์ฑ โ
๋ฌธ์ 1: ๋ชจ๋ ์ฌ์ฉ์๊ฐ ๋ด๋ถ ๋์์ ์์์ผ ํจ.
๋ฌธ์ 2: ๊ฐ์ ๋ก์ง์ด ์ฌ๋ฌ ๊ณณ์ ์ค๋ณต.
๋ฌธ์ 3: ๋๊ตฌ๋ balance ๋ฅผ ์ง์ ๋ง์ง โ ๋ฌด๊ฒฐ์ฑ X.
๋ฌธ์ 4: ์์ ์์ก๋ ๊ฐ๋ฅ (account.balance = -99999).
public class BankAccount {
private int balance; // private โ ์ง์ ์ ๊ทผ X
public void deposit(int amount) {
if (amount <= 0) {
throw new IllegalArgumentException("์
๊ธ์ก์ ์์์ฌ์ผ ํฉ๋๋ค");
}
this.balance += amount;
}
public void withdraw(int amount) {
if (amount <= 0) {
throw new IllegalArgumentException("์ถ๊ธ์ก์ ์์์ฌ์ผ ํฉ๋๋ค");
}
if (this.balance < amount) {
throw new IllegalStateException("์์ก ๋ถ์กฑ");
}
this.balance -= amount;
}
public int getBalance() {
return this.balance;
}
}
์ฌ์ฉ:
BankAccount account = new BankAccount();
account.deposit(10000); // ์
๊ธ
account.withdraw(3000); // ์ถ๊ธ
int current = account.getBalance();
// ์์ ์ฑ โ
account.withdraw(99999); // โ ์์ธ! ์์ก ๋ถ์กฑ
account.deposit(-100); // โ ์์ธ! ์์๋ง ๊ฐ๋ฅ
// account.balance = -1; // โ ์ปดํ์ผ ์๋ฌ! private
| ๋ฉ์๋ ์์ | ๋ฉ์๋ ์์ | |
|---|---|---|
| ์ฝ๋ ์ค๋ณต | ๋งค๋ฒ ์ธ๋ถ์์ ์์ฑ | ํ ๋ฒ ์ ์ ํ ์ฌ์ฌ์ฉ |
| ๋ฐ์ดํฐ ๋ณดํธ | ๋๊ตฌ๋ ์ง์ ๋ณ๊ฒฝ | ๋ฉ์๋๋ฅผ ํตํด์๋ง |
| ๊ฒ์ฆ ๋ก์ง | ํธ์ถ์๊ฐ ์์์ | ๋ฉ์๋ ์์ ํ ๋ฒ๋ง |
| ๋ณ๊ฒฝ ์ํฅ | ๋ชจ๋ ํธ์ถ์ ์์ | ๋ฉ์๋๋ง ์์ |
| ๊ฐ๋ ์ฑ | ๋ฎ์ | ๋์ |
โ ๋ฉ์๋๋ ๊ฐ์ฒด์งํฅ์ ํต์ฌ ๋๊ตฌ. ๋ฉ์๋ ์์ด๋ ์บก์ํ๋, ๋คํ์ฑ๋ ๋ถ๊ฐ๋ฅ.
์๋ฐ ๋ฉ์๋์ ํ์ค ํํ:
[์ ๊ทผ์ ์ด์] [๊ธฐํ์ ์ด์] ๋ฐํํ์
๋ฉ์๋๋ช
(๋งค๊ฐ๋ณ์๋ชฉ๋ก) [throws ์์ธ] {
// ๋ฉ์๋ ๋ณธ๋ฌธ
return ๋ฐํ๊ฐ;
}
์ค์ ์์:
public static int calculateTotal(int price, int quantity) throws IllegalArgumentException {
if (price < 0 || quantity < 0) {
throw new IllegalArgumentException("์์ ๋ถ๊ฐ");
}
return price * quantity;
}
๊ฐ ๋ถ๋ถ์ ๋ถํดํด๋ณด๋ฉด:
| ๋ถ๋ถ | ์์ | ์ญํ |
|---|---|---|
| ์ ๊ทผ ์ ์ด์ | public | ๋๊ฐ ํธ์ถํ ์ ์๋๊ฐ |
| ๊ธฐํ ์ ์ด์ | static | ์ธ์คํด์ค ์์ด ํธ์ถ ๊ฐ๋ฅ |
| ๋ฐํ ํ์ | int | ์ด๋ค ๊ฒฐ๊ณผ๋ฅผ ์ฃผ๋๊ฐ |
| ๋ฉ์๋๋ช | calculateTotal | ๋ฌด์์ ํ๋๊ฐ |
| ๋งค๊ฐ๋ณ์ | (int price, int quantity) | ๋ฌด์์ ์ ๋ ฅ๋ฐ๋๊ฐ |
| ์์ธ ์ ์ธ | throws IllegalArgumentException | ์ด๋ค ์์ธ๋ฅผ ๋์ง ์ ์๋๊ฐ |
| ๋ณธ๋ฌธ | { ... } | ์ค์ ๋ก์ง |
| ๋ฐํ๋ฌธ | return price * quantity; | ๊ฒฐ๊ณผ๋ฅผ ๋๋ ค์ค |
| ์ ์ด์ | ๊ฐ์ ํด๋์ค | ๊ฐ์ ํจํค์ง | ์์ ํด๋์ค (๋ค๋ฅธ ํจํค์ง) | ๊ทธ ์ธ |
|---|---|---|---|---|
public | โ | โ | โ | โ |
protected | โ | โ | โ | โ |
| (default) | โ | โ | โ | โ |
private | โ | โ | โ | โ |
์์น: ๊ฐ์ฅ ์ข์ ๋ฒ์๋ก ์์ โ ํ์ํ ๋๋ง ๋ํ (์บก์ํ ์์น)
์ค๋ฌด ์์:
public class Fare {
private int amount; // ์ธ๋ถ ์ฐจ๋จ โ ๊ฐ์ฅ ์์
public int getAmount() { ... } // ์ธ๋ถ ์กฐํ์ฉ โ ๊ณต๊ฐ
protected void onAmountChanged() { ... } // ์์๋ง ์ฌ์ฉ ๊ฐ๋ฅ
void internalUpdate() { ... } // ๊ฐ์ ํจํค์ง๋ง (default)
private void validate() { ... } // ํด๋์ค ๋ด๋ถ๋ง
}
์๊ธฐ ํ: public > protected > default > private ์์ผ๋ก ์ข์์ง.
// 1. ๊ธฐ๋ณธํ
public int getAge() { return 25; }
public double getPrice() { return 9.99; }
public boolean isActive() { return true; }
// 2. ๊ฐ์ฒด
public String getName() { return "Alice"; }
public Customer getCustomer() { return this.customer; }
// 3. ๋ฐฐ์ด
public int[] getScores() { return new int[]{90, 85, 70}; }
// 4. ์ปฌ๋ ์
public List<String> getTags() { return List.of("a", "b"); }
// 5. ๋ฐํ ์์
public void doSomething() {
System.out.println("์์
์๋ฃ");
// return ์์ (์๋ ์ข
๋ฃ) ๋๋ return; ๊ฐ๋ฅ
}
void ์ return ์ ๋ฏธ๋ฌํ ๊ด๊ณvoid ๋ "๊ฐ์ ๋ฐํํ์ง ์๋๋ค" ๋ ์๋ฏธ:
public void greet(String name) {
System.out.println("Hello, " + name);
// return ์๋ต ๊ฐ๋ฅ (์๋ ์ข
๋ฃ)
}
๊ทธ๋ฌ๋ return; (๊ฐ ์๋ return) ์ ์ฌ์ฉ ๊ฐ๋ฅ โ ๋ฉ์๋ ์ฆ์ ์ข
๋ฃ์ฉ:
public void greet(String name) {
if (name == null) {
return; // โ
์ฆ์ ์ข
๋ฃ, ์ดํ ์ฝ๋ ์คํ X
}
System.out.println("Hello, " + name); // name์ด null์ด๋ฉด ์คํ ์ ๋จ
}
return value; ๋ ๋ถ๊ฐ:
public void doSomething() {
return 42; // โ ์ปดํ์ผ ์๋ฌ: void ๋ฉ์๋๋ ๊ฐ ๋ฐํ X
}
์์ฃผ ํท๊ฐ๋ฆฌ๋ ์ฉ์ด:
// ๋งค๊ฐ๋ณ์ (Parameter) โ ๋ฉ์๋ ์ ์ ์
public int add(int a, int b) { // โ a, b๊ฐ ๋งค๊ฐ๋ณ์
return a + b;
}
// ์ธ์ (Argument) โ ํธ์ถ ์ ์ ๋ฌํ๋ ์ค์ ๊ฐ
int result = add(3, 5); // โ 3, 5๊ฐ ์ธ์
๋น์ :
public class Calculator {
public int add(int a, int b) {
int sum = a + b;
return sum;
}
}
Calculator calc = new Calculator();
int result = calc.add(3, 5);
JVM ๋ด๋ถ ํ๋ฆ โญ :
[Stack ์์ญ] [Heap ์์ญ]
main()
- calc (์ฐธ์กฐ) โโโโโโโโ Calculator ์ธ์คํด์ค
- result โ
โ
add() ํธ์ถ ์ โ
โโโโโโโโโโโโโโโโโโโโ โ
โ add() โ ์ ์คํ ํ๋ ์ โ
โ - this (์๊ธฐ ๊ฐ์ฒด) โโโโโโโโโโโ
โ - a = 3
โ - b = 5
โ - sum = 8
โโโโโโโโโโโโโโโโโโโโ
โ return ํ
add() ์คํ ํ๋ ์ ์ ๊ฑฐ
result = 8
ํต์ฌ ๋์:
1. add(3, 5) ํธ์ถ ์ Stack์ ์ ํ๋ ์ ์์ฑ
2. ๋งค๊ฐ๋ณ์ a=3, b=5 ๊ฐ ์ ํ๋ ์์ ๋ณต์ฌ (Pass by Value)
3. ๋ฉ์๋ ์์ ์ง์ญ๋ณ์ sum ๋ ์ ํ๋ ์์ ์์ฑ
4. return ์ ๊ฒฐ๊ณผ๊ฐ์ ๋ฐํ๋ฐ๋ ๋ณ์์ ๋ณต์ฌ
5. ๋ฉ์๋ ์ข
๋ฃ โ Stack ํ๋ ์ ์ ๊ฑฐ
โ ์ด๊ฒ 4์ฃผ์ฐจ JVM ๋ฉ๋ชจ๋ฆฌ ๋ชจ๋ธ์ ๊ธฐ์ด.
this โ ๋ฉ์๋ ํธ์ถ์ ์จ์ ์ฃผ์ธ๊ณตpublic class Counter {
private int count = 0;
public void increment() {
this.count++; // this = ํธ์ถํ ๊ฐ์ฒด
}
}
Counter c1 = new Counter();
Counter c2 = new Counter();
c1.increment(); // this = c1, c1.count = 1
c1.increment(); // this = c1, c1.count = 2
c2.increment(); // this = c2, c2.count = 1
JVM์ ๋น๋ฐ โญ :
c1.increment() ๋ ์ฌ์ค ์ปดํ์ผ๋ฌ๊ฐ Counter.increment(c1) ์ผ๋ก ๋ณํthis ๋ก ์ ๋ฌ๋จโ Java๊ฐ ๊ฐ์ฒด์ ๋ฉ์๋๋ฅผ ์ฐ๊ฒฐํ๋ ํต์ฌ ๋ฉ์ปค๋์ฆ.
"๊ฐ์ ์ด๋ฆ, ๋ค๋ฅธ ์๊ทธ๋์ฒ"
public class Calculator {
public int add(int a, int b) { return a + b; }
public double add(double a, double b) { return a + b; }
public int add(int a, int b, int c) { return a + b + c; }
public String add(String a, String b) { return a + b; }
}
calc.add(1, 2); // ์ฒซ ๋ฒ์งธ ํธ์ถ
calc.add(1.5, 2.5); // ๋ ๋ฒ์งธ ํธ์ถ
calc.add(1, 2, 3); // ์ธ ๋ฒ์งธ ํธ์ถ
calc.add("Hi", " Bob"); // ๋ค ๋ฒ์งธ ํธ์ถ
์ค๋ฒ๋ก๋ฉ ๊ท์น โญ :
public int foo() { ... }
public String foo() { ... } // โ ์ปดํ์ผ ์๋ฌ
์ ๋ฐํ ํ์ ๋ง ๋ค๋ฅด๋ฉด ์ ๋๋?
obj.foo(); ๋ง์ผ๋ก๋ int ๋ฉ์๋์ธ์ง String ๋ฉ์๋์ธ์ง ๊ตฌ๋ณ ๋ถ๊ฐJVM ๋ด๋ถ์ ๋ฉ์๋ ์๋ณ โญ :
์๋ฐ๋ ํญ์ ๊ฐ์ผ๋ก ์ ๋ฌ(Pass by Value) ํฉ๋๋ค. (4์ฃผ์ฐจ์์ ๊น์ด ๋ค๋ฃธ)
๊ธฐ๋ณธํ ๋งค๊ฐ๋ณ์:
public void changeNumber(int x) {
x = 100; // ๋ฉ์๋ ๋ด๋ถ์ x๋ง ๋ณ๊ฒฝ
}
int num = 10;
changeNumber(num);
System.out.println(num); // 10 (๋ณ๊ฒฝ ์ ๋จ)
๊ฐ์ฒด ๋งค๊ฐ๋ณ์ (์ฐธ์กฐ์ ๊ฐ ์ ๋ฌ):
public void changeName(Person p) {
p.setName("Bob"); // ๊ฐ์ฒด ๋ด๋ถ ๋ณ๊ฒฝ โ ์ธ๋ถ ์ํฅ โ
}
public void replacePerson(Person p) {
p = new Person("Bob"); // ๋ฉ์๋ ๋ด๋ถ์ ์ฐธ์กฐ๋ง ๋ณ๊ฒฝ
}
Person alice = new Person("Alice");
changeName(alice);
System.out.println(alice.getName()); // "Bob" (๊ฐ์ฒด ๋ด๋ถ ๋ณ๊ฒฝ๋จ)
Person charlie = new Person("Charlie");
replacePerson(charlie);
System.out.println(charlie.getName()); // "Charlie" (์ฐธ์กฐ ๋ณ๊ฒฝ ์ ๋จ)
โ 4์ฃผ์ฐจ์์ ์์ธํ ๋ค๋ฃฐ ์ฃผ์ . ์ง๊ธ์ "์๋ฐ๋ ํญ์ ๊ฐ ์ ๋ฌ" ๋ง ๊ธฐ์ต.
ILIC ์ด์ ์์คํ ์ผ๋ก ๋ฉ์๋๋ฅผ ๋ค์ํ ํํ๋ก ๋ณด๊ฒ ์ต๋๋ค.
public class FareService {
private final FareRepository repository;
// 1. ๋งค๊ฐ๋ณ์ X, ๋ฐํ X
public void initialize() {
System.out.println("FareService ์ด๊ธฐํ");
}
// 2. ๋งค๊ฐ๋ณ์ X, ๋ฐํ O
public int getCount() {
return repository.count();
}
// 3. ๋งค๊ฐ๋ณ์ O, ๋ฐํ X
public void delete(Long id) {
repository.deleteById(id);
}
// 4. ๋งค๊ฐ๋ณ์ O, ๋ฐํ O
public Fare findById(Long id) {
return repository.findById(id)
.orElseThrow(() -> new EntityNotFoundException("์ด์ ์์"));
}
// 5. ์ฌ๋ฌ ๋งค๊ฐ๋ณ์, ๋ณต์กํ ๋ฐํ
public List<Fare> search(Long customerId, FareStatus status, LocalDate from, LocalDate to) {
return repository.findByCriteria(customerId, status, from, to);
}
}
public class Fare {
private int amount; // ์ธ๋ถ ์ ๊ทผ ๋ถ๊ฐ
private FareStatus status;
// public โ ์ธ๋ถ API
public void changeAmount(int newAmount) {
validateAmount(newAmount); // ๋ด๋ถ ํธ์ถ
this.amount = newAmount;
notifyChange();
}
// protected โ ์์ ํด๋์ค์์ ์ค๋ฒ๋ผ์ด๋ ๊ฐ๋ฅ
protected void notifyChange() {
System.out.println("์ด์ ๋ณ๊ฒฝ๋จ");
}
// package-private (default) โ ๊ฐ์ ํจํค์ง๋ง
void internalReset() {
this.amount = 0;
this.status = FareStatus.DRAFT;
}
// private โ ํด๋์ค ๋ด๋ถ๋ง
private void validateAmount(int amount) {
if (amount < 0) {
throw new IllegalArgumentException("์์ ๋ถ๊ฐ");
}
}
public int getAmount() { return amount; }
}
์ข์ ์ค๊ณ์ ์ ํธ:
private ๊ฐ ๊ฐ์ฅ ๋ง์ (๋ด๋ถ ๊ตฌํ)public ์ ๋ช
ํํ ์ธ๋ถ API๋งprotected, default ๋ ์๋์ ์ธ ๊ฒฝ์ฐ๋งpublic class FareCalculator {
// ๊ธฐ๋ณธ ๊ฑฐ๋ฆฌ ๊ณ์ฐ
public int calculate(int distance) {
return distance * 500;
}
// ๊ฑฐ๋ฆฌ + ๋ฌด๊ฒ
public int calculate(int distance, int weight) {
return distance * 500 + weight * 100;
}
// ๊ฑฐ๋ฆฌ + ๋ฌด๊ฒ + ๊ธด๊ธ ์ฌ๋ถ
public int calculate(int distance, int weight, boolean urgent) {
int base = calculate(distance, weight);
return urgent ? base * 2 : base;
}
// FareRequest ๊ฐ์ฒด๋ก
public int calculate(FareRequest request) {
return calculate(
request.getDistance(),
request.getWeight(),
request.isUrgent()
);
}
}
// ์ฌ์ฉ โ ๊ฐ์ ์ด๋ฆ์ผ๋ก ๋ค์ํ ํธ์ถ
calc.calculate(100); // 50000
calc.calculate(100, 50); // 55000
calc.calculate(100, 50, true); // 110000
calc.calculate(new FareRequest(100, 50, true)); // 110000
ํจ๊ณผ: ์ฌ์ฉ์๋ calculate ๋ผ๋ ํ ์ด๋ฆ ๋ง ๊ธฐ์ตํ๋ฉด ๋จ. ๋ค์ํ ์๋๋ฆฌ์ค๋ฅผ ํ ๋ฉ์๋๋ช
์ผ๋ก ์ฒ๋ฆฌ.
public class FareValidator {
public void validate(Fare fare) {
// Early Return ํจํด โญ
if (fare == null) {
return; // ์ฆ์ ์ข
๋ฃ
}
if (fare.getAmount() < 0) {
throw new IllegalArgumentException("์์ ์ด์");
}
if (fare.getStatus() == null) {
throw new IllegalStateException("์ํ ์์");
}
// ๋ชจ๋ ๊ฒ์ฆ ํต๊ณผ
System.out.println("๊ฒ์ฆ OK");
}
}
Early Return ํจํด:
Bad (์ค์ฒฉ):
public void validate(Fare fare) {
if (fare != null) {
if (fare.getAmount() >= 0) {
if (fare.getStatus() != null) {
// ๊ฒ์ฆ OK โ ๋ค์ฌ์ฐ๊ธฐ ์ง์ฅ โ
}
}
}
}
Good (Early Return):
public void validate(Fare fare) {
if (fare == null) return;
if (fare.getAmount() < 0) throw new IllegalArgumentException();
if (fare.getStatus() == null) throw new IllegalStateException();
// ๋ฉ์ธ ๋ก์ง โ ํํํ ๊ตฌ์กฐ โ
}
// โ ๋ช
์ฌ โ ๋ฉ์๋์ธ์ง ๋ณ์์ธ์ง ๋ชจํธ
public int total() { ... }
public String name() { ... }
// โ
๋์ฌ โ ์๋ ๋ช
ํ
public int calculateTotal() { ... }
public String getName() { ... }
public boolean isActive() { ... } // ์ง์ํ์ is/has/can์ผ๋ก
๊ท์น โญ :
calculate, find, save)getName, getAge)isActive, hasPermission, canDelete)// โ ๋งค๊ฐ๋ณ์ 7๊ฐ
public Fare createFare(
Long customerId,
int amount,
String currency,
LocalDate departureDate,
String origin,
String destination,
boolean urgent
) { ... }
๋ฌธ์ :
createFare(1L, 50000, "KRW", date, "์์ธ", "๋ถ์ฐ", true);
createFare(1L, 50000, "KRW", date, "๋ถ์ฐ", "์์ธ", true); // ์ถ๋ฐ-๋์ฐฉ ๋ฐ๋! โ
ํด๊ฒฐ โ ๊ฐ์ฒด๋ก ๋ฌถ๊ธฐ:
public Fare createFare(FareCreateRequest request) { ... }
public record FareCreateRequest(
Long customerId,
int amount,
String currency,
LocalDate departureDate,
Route route, // origin, destination ๋ฌถ์
boolean urgent
) {}
์์น: ๋งค๊ฐ๋ณ์ 4๊ฐ ์ด์์ด๋ฉด ๊ฐ์ฒด๋ก ๋ฌถ๊ธฐ ๊ฒํ .
// โ ๋งค๊ฐ๋ณ์๋ฅผ ๋ณ๊ฒฝ โ ํผ๋ ์ผ๊ธฐ
public int processAmount(int amount) {
amount = amount * 2; // ๋งค๊ฐ๋ณ์ ์์ฒด๋ฅผ ๋ณ๊ฒฝ
if (amount > 10000) {
amount = 10000;
}
return amount;
}
๋ฌธ์ :
ํด๊ฒฐ โ ๋งค๊ฐ๋ณ์๋ final, ์ ๋ณ์ ์ฌ์ฉ:
public int processAmount(final int amount) {
int result = amount * 2;
if (result > 10000) {
result = 10000;
}
return result;
}
public void doSomething() {
int result = ...;
return result; // โ ์ปดํ์ผ ์๋ฌ
}
ํด๊ฒฐ:
return; ๋ง (๊ฐ ์์ด)// โ ๋ฉ์๋ ํ๋๊ฐ 200์ค
public void processOrder(Order order) {
// 1. ๊ฒ์ฆ (50์ค)
// 2. ๊ณ์ฐ (50์ค)
// 3. ์ ์ฅ (30์ค)
// 4. ์๋ฆผ (40์ค)
// 5. ๋ก๊น
(30์ค)
}
๋ฌธ์ :
ํด๊ฒฐ โ ์์ ๋ฉ์๋๋ก ๋ถ๋ฆฌ:
public void processOrder(Order order) {
validate(order);
int total = calculate(order);
save(order);
notify(order);
log(order);
}
private void validate(Order order) { ... }
private int calculate(Order order) { ... }
private void save(Order order) { ... }
private void notify(Order order) { ... }
private void log(Order order) { ... }
๊ถ์ฅ: ๋ฉ์๋๋ ํ ํ๋ฉด์ ๋ค์ด์ค๋ ์ ๋ (๋ณดํต 20์ค ์ด๋ด).
public class Calculator {
public void process(int x) { ... }
public void process(Integer x) { ... } // โ ๏ธ Auto-boxing ๋ชจํธํจ
}
calc.process(10); // int? Integer? ์ปดํ์ผ๋ฌ๊ฐ ์ฐ์ ์์ ๊ฒฐ์
์์น:
[Unit 2.1: ๋ฉ์๋์ ๊ตฌ์กฐ] โ ์ง๊ธ ์ฌ๊ธฐ
โ
[Unit 2.2: ๊ฐ๋ณ์ธ์] โ ๋ค์ ํ์ต
โ
[Unit 2.3: ์์๊ณผ ์์ฑ์ ์ฒด์ด๋]
โ
[Unit 2.4: ๋คํ์ฑ] โ
โ OOP์ ์ ์
1์ฃผ์ฐจ ๋ด:
๋ฏธ๋ ์ฃผ์ฐจ:
<T> T foo(T input))@PreAuthorize ๊ฐ ๋ฉ์๋ ๋จ์ ๊ถํ ๊ฒ์ฆ| ํจํด | ๋ฉ์๋ ํ์ฉ |
|---|---|
| Strategy | ์ธํฐํ์ด์ค ๋ฉ์๋๋ฅผ ๋ค์ํ๊ฒ ๊ตฌํ |
| Template Method | ์์ ๋ฉ์๋๊ฐ ํ๋ฆ, ํ์ ๋ฉ์๋๊ฐ ๊ตฌํ |
| Factory Method | ๊ฐ์ฒด ์์ฑ์ ๋ฉ์๋๋ก ์บก์ํ |
| Builder | ๋ฉ์๋ ์ฒด์ด๋์ผ๋ก ๊ฐ์ฒด ๊ตฌ์ฑ |
โ 5์ฃผ์ฐจ์์ ๋ณธ๊ฒฉ ํ์ต.
| ์ง๋ฌธ | ์ด Unit์์์ ๋ต |
|---|---|
| "๋ฉ์๋ ์ค๋ฒ๋ก๋ฉ์ด ๋ญ๊ฐ์?" | ๊ฐ์ ์ด๋ฆ, ๋ค๋ฅธ ์๊ทธ๋์ฒ (ํ์ /๊ฐ์/์์) |
| "์ค๋ฒ๋ก๋ฉ๊ณผ ์ค๋ฒ๋ผ์ด๋ฉ์ ์ฐจ์ด๋?" | ์ค๋ฒ๋ก๋ฉ=๊ฐ์ ํด๋์ค ๋ค๋ฅธ ์๊ทธ๋์ฒ, ์ค๋ฒ๋ผ์ด๋ฉ=์์์์ ๋ฉ์๋ ์ฌ์ ์ (Unit 2.4) |
| "์ ๊ทผ ์ ์ด์ 4๊ฐ์ง ์ฐจ์ด๋?" | public > protected > default > private |
| "Pass by Value vs Reference?" | ์๋ฐ๋ ํญ์ Pass by Value (4์ฃผ์ฐจ์์ ์์ธํ) |
| "void์์ return ๊ฐ๋ฅ?" | ๊ฐ ์๋ return; ๋ง ๊ฐ๋ฅ |
1๏ธโฃ ๋ฉ์๋๋ "๊ฐ์ฒด์ ํ๋์ ์ ์ํ๋ ๋จ์" ๋ค.
์ ์ฐจ์งํฅ์ ํจ์๊ฐ ๊ฐ์ฒด์ ๋ฌถ์ธ ํํ๋ก, ์๊ทธ๋์ฒ(์ ๊ทผ์ ์ด์ + ๋ฐํํ์ + ๋ฉ์๋๋ช + ๋งค๊ฐ๋ณ์) ๋ก ๊ตฌ์ฑ๋๋ค. ๋ฉ์๋ ์์ด๋ ์บก์ํ๋ ๋คํ์ฑ๋ ๋ถ๊ฐ๋ฅํ๋ฏ๋ก, ๊ฐ์ฒด์งํฅ์ ๊ฐ์ฅ ๊ธฐ๋ณธ ๋๊ตฌ ๋ค.
2๏ธโฃ ์ ๊ทผ ์ ์ด์๋ก "๋๊ฐ ํธ์ถํ ์ ์๋๊ฐ" ๋ฅผ ํต์ ํ๋ค.
private๋ถํฐ ์์ํด์ ํ์ํ ๋๋ง ๋ํ๋ ๊ฒ์ด ์บก์ํ์ ํต์ฌ. public > protected > default > private ์์ผ๋ก ์ข์์ง๋ฉฐ, ์ข์์๋ก ์์ ํ๋ค. ILIC ๊ฐ์ ํฐ ์์คํ ์์๋ ์๋์ ์ธ ์ ๊ทผ ์ ์ด๊ฐ ์ ์ง๋ณด์ ๋น์ฉ์ ๊ฒฐ์ ํ๋ค.3๏ธโฃ ์ข์ ๋ฉ์๋๋ "ํ ๊ฐ์ง ์ผ๋ง, ์งง๊ฒ, ๋ช ํํ ์ด๋ฆ์ผ๋ก" ํ๋ค.
๋งค๊ฐ๋ณ์ 4๊ฐ ์ด์์ด๋ฉด ๊ฐ์ฒด๋ก ๋ฌถ๊ธฐ, ๋ฉ์๋๋ ํ ํ๋ฉด์ ๋ค์ด์ค๊ฒ (20์ค ๋ด์ธ), ๋์ฌ ์์ ์ด๋ฆ (
calculate,find,save), ๋งค๊ฐ๋ณ์๋ ์์์ ๋ณ๊ฒฝ X โ ์ด ๊ท์น๋ค์ด ์ฝ๋ ํ์ง์ ๊ฒฐ์ ํ๋ค.
void ๋ฉ์๋์์ return; ์ ์๋ฏธ๋ฅผ ์ค๋ช
ํ ์ ์๋คQ1: void ๋ฐํ ํ์
์ ๋ฉ์๋์์ return์ ์ธ ์ ์๋๊ฐ?
YES. ๋จ, ๊ฐ ์๋ return; ๋ง ๊ฐ๋ฅ. ๋ฉ์๋๋ฅผ ์ฆ์ ์ข
๋ฃ ํ๋ ์ฉ๋.
public void greet(String name) {
if (name == null) {
return; // โ
์ฆ์ ์ข
๋ฃ
}
System.out.println("Hello, " + name);
}
public void doSomething() {
return 42; // โ ๊ฐ์ด ์๋ return ๋ถ๊ฐ
}
ํ์ฉ: Early Return ํจํด โ ์กฐ๊ฑด์ ๋ง์ง ์์ผ๋ฉด ์ฆ์ ์ข ๋ฃํด์ ์ค์ฒฉ if ์ค์ด๊ธฐ.
Q2: ๋งค๊ฐ๋ณ์ ์๋ ๋ฉ์๋์ ์๋ ๋ฉ์๋์ ํธ์ถ ๋ฐฉ์ ์ฐจ์ด๋?
ํธ์ถ ์ ๊ดํธ ์์ ์ธ์๋ฅผ ๋๊ธฐ๋๋์ ์ฐจ์ด:
// ๋งค๊ฐ๋ณ์ ์์ โ ๋น ๊ดํธ
obj.method();
// ๋งค๊ฐ๋ณ์ ์์ โ ์ธ์ ์ ๋ฌ
obj.method(arg1, arg2);
โ ๏ธ ์ฃผ์ โ ๊ดํธ๋ ํญ์ ํ์:
obj.method; // โ ๋ฉ์๋ ํธ์ถ ์๋ (๋ฉ์๋ ์ฐธ์กฐ๋ก ํด์๋๊ฑฐ๋ ์๋ฌ)
obj.method(); // โ
ํธ์ถ
โ ๏ธ ๋ฉ์๋ ์ฐธ์กฐ ์์ ์ฐจ์ด (3์ฃผ์ฐจ ๋๋ค์ ์ฐ๊ฒฐ):
list.forEach(System.out::println); // ๋ฉ์๋ ์ฐธ์กฐ (ํธ์ถ X)
list.forEach(x -> System.out.println(x)); // ๋๋ค