๋ณธ๋ฌธ์œผ๋กœ ๊ฑด๋„ˆ๋›ฐ๊ธฐ

๐ŸŒˆ Chapter 6: ๋Œ์•„์˜จ "๋ชจ๋‘๋ฅผ ์œ„ํ•œ ํ‰๋“ฑ"

์‹ค์ œ๋กœ ์ƒˆ๋กœ์šด ํ…Œ์ŠคํŠธ ์ผ€์ด์Šค๋ฅผ ํ•˜๋‚˜ ์ž‘๋™ํ•˜๊ฒŒ ๋งŒ๋“ค์—ˆ๋‹ค. ํ•˜์ง€๋งŒ ํ…Œ์ŠคํŠธ๋ฅผ ๋นจ๋ฆฌ ํ†ต๊ณผํ•˜๊ธฐ ์œ„ํ•ด ๋ช‡ ํ†ค์ด๋‚˜ ๋˜๋Š” ์ฝ”๋“œ๋ฅผ ๋ณต์‚ฌํ•ด์„œ ๋ถ™์ด๋Š” ์—„์ฒญ๋‚œ ์ฃ„๋ฅผ ์ €์งˆ๋ €๋‹ค. ์ด์ œ ์ฒญ์†Œํ•  ์‹œ๊ฐ„์ด๋‹ค.

๊ฐ€๋Šฅํ•œ ๋ฐฉ๋ฒ• ํ•œ ๊ฐ€์ง€๋Š” ์šฐ๋ฆฌ๊ฐ€ ๋งŒ๋“  ํด๋ž˜์Šค ์ค‘ ํ•˜๋‚˜๊ฐ€ ๋‹ค๋ฅธ ํด๋ž˜์Šค๋ฅผ ์ƒ์†๋ฐ›๊ฒŒ ํ•˜๋Š” ๊ฒƒ์ด๋‹ค. ๋‚ด๊ฐ€ ๊ทธ๋ ‡๊ฒŒ ํ•ด๋ดค๋Š”๋ฐ, ๊ฑฐ์˜ ์–ด๋–ค ์ฝ”๋“œ๋„ ๊ตฌ์›ํ•˜์ง€ ๋ชปํ–ˆ๋‹ค. ๋Œ€์‹ , ๋‘ ํด๋ž˜์Šค์˜ ๊ณตํ†ต ์ƒ์œ„ ํด๋ž˜์Šค๋ฅผ ์ฐพ์•„๋‚ผ ์ƒ๊ฐ์ด๋‹ค.
Moneyํด๋ž˜์Šค๊ฐ€ ๊ณตํ†ต์˜ equals ์ฝ”๋“œ๋ฅผ ๊ฐ–๊ฒŒ ํ•˜๋ฉด ์–ด๋–จ๊นŒ? ๊ฐ„๋‹จํ•œ ๊ฒƒ๋ถ€ํ„ฐ ์‹œ์ž‘ํ•ด๋ณด์ž.

class Money

๋ชจ๋“  ํ…Œ์ŠคํŠธ๋Š” ์—ฌ์ „ํžˆ ๋Œ์•„๊ฐˆ ๊ฒƒ์ด๋‹ค. ๋ญ”๊ฐ€๋ฅผ ๊นจํŠธ๋ ธ์„ ๊ฒƒ ๊ฐ™์ง€๋Š” ์•Š๋‹ค. ์–ด์จŒ๊ฑด ํ…Œ์ŠคํŠธ๋ฅผ ๋Œ๋ ค๋ณด๊ธฐ ์ข‹์€ ๋•Œ๋‹ค. Dollar๊ฐ€ Money๋ฅผ ์ƒ์†๋ฐ›๋Š”๋‹ค๊ณ  ํ•ด๋„ ์—ฌ์ „ํžˆ ์–ด๋–ค ๊ฒƒ๋„ ๊บ ์ง€์ง€ ์•Š๋Š”๋‹ค.

class Dollar extends Money {
private int amount;
}

๋ญ”๊ฐ€ ๊นจ์กŒ๋‚˜? ์•„๋‹ˆ๋‹ค. ํ…Œ์ŠคํŠธ๋Š” ์—ฌ์ „ํžˆ ์ž˜ ๋ˆ๋‹ค. ์ด์ œ amount ์ธ์Šคํ„ด์Šค ๋ณ€์ˆ˜๋ฅผ Money๋กœ ์˜ฎ๊ธธ ์ˆ˜ ์žˆ๋‹ค.

class Money {
protected int amount;
}

class Dollar extends Money {
}

ํ•˜์œ„ ํด๋ž˜์Šค์—์„œ๋„ ๋ณ€์ˆ˜๋ฅผ ๋ณผ ์ˆ˜ ์žˆ๋„๋ก ๊ฐ€์‹œ์„ฑ์„ private์—์„œ protected๋กœ ๋ณ€๊ฒฝํ–ˆ๋‹ค.
์ด์ œ equals() ์ฝ”๋“œ๋ฅผ ์œ„๋กœ ์˜ฌ๋ฆฌ๋Š” ์ผ์„ ํ•  ์ˆ˜ ์žˆ๊ฒŒ ๋๋‹ค. ์šฐ์„  ์ž„์‹œ๋ณ€์ˆ˜๋ฅผ ์„ ์–ธํ•˜๋Š” ๋ถ€๋ถ„์„ ๋ณ€๊ฒฝํ•˜์ž.

public boolean equals(Object object) {
Money dollar = (Dollar) object;
return amount == dollar.amount;
}

๋ชจ๋“  ํ…Œ์ŠคํŠธ๊ฐ€ ์—ฌ์ „ํžˆ ์ž˜ ๋ˆ๋‹ค. ์ด์ œ ์บ์ŠคํŠธ(cast) ๋ถ€๋ถ„์„ ๋ณ€๊ฒฝํ•˜์ž.

public boolean equals(Object object) {
Money dollar = (Money) object;
return amount == dollar.amount;
}

์ข€๋” ์›ํ™œํ•œ ์˜์‚ฌ์†Œํ†ต์„ ์œ„ํ•ด ์ž„์‹œ ๋ณ€์ˆ˜์˜ ์ด๋ฆ„์„ ๋ณ€๊ฒฝํ•˜์ž.

public boolean equals(Object object) {
Money money = (Money) object;
return amount == money.amount;
}

์ด์ œ ์ด ๋ฉ”์„œ๋“œ๋ฅผ Dollar์—์„œ Money๋กœ ์˜ฎ๊ธธ ์ˆ˜ ์žˆ๋‹ค.

์ด์ œ๋Š” Franc.equals()๋ฅผ ์ œ๊ฑฐํ•ด์•ผ ํ•œ๋‹ค. ์ ์ ˆํ•œ ํ…Œ์ŠคํŠธ๋ฅผ ๊ฐ–์ง€ ๋ชปํ•œ ์ฝ”๋“œ์—์„œ TDD๋ฅผ ํ•ด์•ผ ํ•˜๋Š” ๊ฒฝ์šฐ๊ฐ€ ์ข…์ข… ์žˆ์„ ๊ฒƒ์ด๋‹ค. ์ถฉ๋ถ„ํ•œ ํ…Œ์ŠคํŠธ๊ฐ€ ์—†๋‹ค๋ฉด ์ง€์› ํ…Œ์ŠคํŠธ๊ฐ€ ๊ฐ–์ถฐ์ง€์ง€ ์•Š์€ ๋ฆฌํŒฉํ† ๋ง์„ ๋งŒ๋‚˜๊ฒŒ ๋  ์ˆ˜๋ฐ–์— ์—†๋‹ค. ๋ฆฌํŒฉํ† ๋งํ•˜๋ฉด์„œ ์‹ค์ˆ˜ํ–ˆ๋Š”๋ฐ๋„ ๋ถˆ๊ตฌํ•˜๊ณ  ํ…Œ์ŠคํŠธ๊ฐ€ ์—ฌ์ „ํžˆ ํ†ต๊ณผํ•  ์ˆ˜๋„ ์žˆ๋Š” ๊ฒƒ์ด๋‹ค. ์–ด๋–ป๊ฒŒ ํ•  ํ…๊ฐ€?

์žˆ์œผ๋ฉด ์ข‹์„ ๊ฒƒ ๊ฐ™์€ ํ…Œ์ŠคํŠธ๋ฅผ ์ž‘์„ฑํ•˜๋ผ. ๊ทธ๋ ‡๊ฒŒ ํ•˜์ง€ ์•Š์œผ๋ฉด ๊ฒฐ๊ตญ์—๋Š” ๋ฆฌํŒฉํ† ๋งํ•˜๋‹ค๊ฐ€ ๋ญ”๊ฐ€ ๊นจํŠธ๋ฆด ๊ฒƒ์ด๋‹ค. ๊ทธ๋Ÿฌ๋ฉด ์—ฌ๋Ÿฌ๋ถ„์€ ๋ฆฌํŒฉํ† ๋ง์— ๋Œ€ํ•ด ์•ˆ ์ข‹์€ ๋Š๋‚Œ์„ ๊ฐ–๊ฒŒ ๋˜๊ณ , ๋ฆฌํŒฉํ† ๋ง์„ ๋œ ํ•˜๊ฒŒ ๋œ๋‹ค. ๋ฆฌํŒฉํ† ๋ง์„ ๋” ์ ๊ฒŒํ•˜๋ฉด ์„ค๊ณ„์˜ ์งˆ์ด ์ €ํ•˜๋˜๊ณ , ๊ฒฐ๊ตญ ์—ฌ๋Ÿฌ๋ถ„์€ ํ•ด๊ณ ๋  ๊ฒƒ์ด๋‹ค. ๋ฆฌํŒฉํ† ๋งํ•˜๊ธฐ ์ „์— ํ…Œ์ŠคํŒ…์„ ํ•˜์ž.

๋‹คํ–‰ํžˆ๋„ ์ด๋ฒˆ ํ…Œ์ŠคํŠธ๋Š” ์ž‘์„ฑํ•˜๊ธฐ ์‰ฝ๋‹ค. ๊ทธ๋ƒฅ Dollar ํ…Œ์ŠคํŠธ๋ฅผ ๋ณต์‚ฌํ•˜์ž.

public void testEquality() {
assertTrue(new Dollar(5).equals(new Dollar(5)));
assertFalse(new Dollar(5).equals(new Dollar(6)));
assertTrue(new Franc(5).equals(new Franc(5)));
assertFalse(new Franc(5).equals(new Franc(6)));
}

๋˜ ์ค‘๋ณต์ด๋‹ค. ๋‘ ์ค„์ด๋‚˜ ๋”! ์ด๋ฒˆ์— ์ €์ง€๋ฅธ ์ฃ„์— ๋Œ€ํ•ด์„œ๋„ ์†์ฃ„ํ•˜๊ฒŒ ๋  ๊ฒƒ์ด๋‹ค.

class Franc extends Money {
private int amount;
}

Money ํด๋ž˜์Šค์— ์žˆ๋Š” ํ•„๋“œ๋ฅผ ์ด์šฉํ•˜๋ฉด Franc์˜ amount ํ•„๋“œ๋ฅผ ์ œ๊ฑฐํ•  ์ˆ˜ ์žˆ๋‹ค.

class Franc extends Money {
}

Franc.equals()๋Š” Money.equals()์™€ ๊ฑฐ์˜ ๋น„์Šทํ•ด ๋ณด์ธ๋‹ค. ์ด ๋‘ ๋ถ€๋ถ„์„ ์™„์ „ํžˆ ๋˜‘๊ฐ™์ด ๋งŒ๋“ค ์ˆ˜ ์žˆ๋‹ค๋ฉด ํ”„๋กœ๊ทธ๋žจ์˜ ์˜๋ฏธ๋ฅผ ๋ณ€ํ™”์‹œํ‚ค์ง€ ์•Š๊ณ  Franc์˜ equals()๋ฅผ ์ง€์›Œ๋ฒ„๋ฆด ์ˆ˜ ์žˆ๊ฒŒ ๋œ๋‹ค. ์šฐ์„  ์ž„์‹œ ๋ณ€์ˆ˜์˜ ์„ ์–ธ ๋ถ€๋ถ„์„ ๊ณ ์น˜์ž.

public boolean equals(Object object) {
Money franc = (Franc) object;
return amount == franc.amount;
}

๊ทธ ๋‹ค์Œ์—” ์บ์ŠคํŠธ ๋ถ€๋ถ„์„ ์ˆ˜์ •ํ•œ๋‹ค.

public boolean equals(Object object) {
Money franc = (Money) object;
return amount == franc.amount;
}

์ž„์‹œ ๋ณ€์ˆ˜์˜ ์ด๋ฆ„๋„ ์ƒ์œ„ ํด๋ž˜์Šค์— ๋งž๊ฒŒ ๊ณ ์ณ์•ผ ํ•˜๋Š” ๊ฑธ๊นŒ? ๊ทธ๊ฑด ์—ฌ๋Ÿฌ๋ถ„์˜ ์–‘์‹ฌ์— ๋งก๊ธฐ๊ฒ ๋‹ค... ๊ทธ๋ž˜, ๊ณ ์ณ๋ณด์ž.

public boolean equals(Object object) {
Money money = (Money) object;
return amount == money.amount;
}

์ด์ œ Franc.equals()์™€ Money.equals() ์‚ฌ์ด์— ๋‹ค๋ฅธ ์ ์ด ์—†์œผ๋ฏ€๋กœ Franc์˜ ๋ถˆํ•„์š”ํ•œ ์ฝ”๋“œ๋ฅผ ์ œ๊ฑฐํ•˜์ž. ๊ทธ๋ฆฌ๊ณ  ํ…Œ์ŠคํŠธ๋ฅผ ๋Œ๋ ค๋ณด์ž. ์ž˜ ๋Œ์•„๊ฐ„๋‹ค.
๊ทธ๋Ÿฐ๋ฐ Franc๊ณผ Dollar๋ฅผ ๋น„๊ตํ•˜๋ฉด ์–ด๋–ป๊ฒŒ ๋ ๊นŒ? ์ด๊ฑด 7์žฅ์—์„œ ๋‹ค๋ฃจ๋„๋ก ํ•˜์ž.