์ดํํฐ๋ธ ์๋ฐ ์คํฐ๋๋ฅผ 9์๋ถํฐ ํ๊ณ ์๋ ์ค์ธ๋ฐ ์ ๋ฒ์ฃผ ์ฃผ์ ์ค์ ์์์ ์๋ฌด๋๋ ์ฌ์ฉํ์ง ๋ง๊ณ ์ฃผ์ํด์ ์ฌ์ฉํ๋ผ๋ผ๋ ์ฃผ์ ๊ฐ ๋์์๋ค.. ๊ทผ๋ฐ ์ฃผ์์ ์ด ๋๋ฌด ๋ง์์ ๊ทธ๋ฌ๋ฉด ์์์ ์์ฐ๋ฉด ๋๋ ๊ฑฐ ์๋๊ฐ์? ํ๋ ๋ง์ด ๋์์์ ์คํฐ๋์์ด ์ ๋ฆฌํ ๊ฒ ์ค์ ์๋์ ๊ฐ์ ๊ธ๋ ์์๋ค.
๐ฌ Java์ ์ฐฝ์์์ธ ์ ์์ค ๊ณ ์ฌ๋ง(James Arthur Gosling)์ด ํ ์ธํฐ๋ทฐ์์ "๋ด๊ฐ ์๋ฐ๋ฅผ ๋ง๋ค๋ฉด์ ๊ฐ์ฅ ํํํ๋ ์ผ์ ์์์ ๋ง๋ ์ ์ด๋ค"๋ผ๊ณ ๋งํ๋ค.
์กฐ์์ผ ๋ธ๋กํฌ์ Effective Java์์๋ ์์์ ์ํ ์ค๊ณ์ ๋ฌธ์๋ฅผ ๊ฐ์ถ๊ฑฐ๋, ๊ทธ๋ด ์ ์๋ค๋ฉด ์์์ ๊ธ์งํ๋ผ๋ ์กฐ์ธ์ ํ๋ค.
๋ฐ๋ผ์ ์ถ์ํ๊ฐ ํ์ํ๋ฉด ์ธํฐํ์ด์ค
๋ก implements ํ๊ฑฐ๋ ๊ฐ์ฒด ์งํฅ ์ค๊ณ๋ฅผ ํ ๋ ํฉ์ฑ(composition)
์ ์ด์ฉํ๋ ๊ฒ์ด ์ถ์ธ์ด๋ค.
ํ์ง๋ง ์ฐ๋ฆฌ๊ฐ ๊ธฐ์ด๋ฅผ ๋ฐฐ์ธ ๋๋ ํญ์ ์์์ ๋ง์ด ๋ฐฐ์ฐ๊ธฐ๋ ํ๊ณ ํด์ ๊ถ๊ธํด์ก๋ค! ๊ทธ๋ฆฌ๊ณ ์ฝํ๋ฆฐ
์ด ์๋ฐ์์์ ๋ถํธํ ์ ์ ๊ฑฐ์ ๋ง์ด ๊ฐ์ ํ ํ๋ก๊ทธ๋๋ฐ ์ธ์ด์ธ๋ฐ ์ด๋ฌํ ์ ๋ ๊ฐ์ ๋์๋์ง ์์๋ณด๊ณ ์ ํจ
์ข ๋ ๋ฅํ๊ฒ ์์์ ์ฐ๊ฒ ๋๋ฉด,
- ๋ฌด์์ด ๋ฌธ์ ์ธ์ง
- ์ ๋ฌธ์ ์ธ์ง
- ๊ทธ๋ ๋ค๋ฉด ์ ํํ ์ธ์ ์ฌ์ฉํด์ผ ํ๋ ๊ฑด์ง ์์๋ณด์..
- ์ดํํฐ๋ธ ์๋ฐ์ ํจ๊ป ๊ทธ๋ฆฌ๊ณ ์ฝํ๋ฆฐ์์ ์์์ด ์๋๊ฐ๋ ์์๋ณด์
ํ์ฌ ์ฝ๋๊ฐ ์ ๋ต์ ์๋์ง๋ง ํ์ฌ ์ฝ๋ ๋ํ ์ดํด๋ณด์๋ค! ์ผ๋จ ์์์ด ๋ฌด์์ธ์ง์ ์ดํํฐ๋ธ ์๋ฐ์์ ๋์์ ์์๋ณด์
์ผ๋ฐ์ ์ธ ๊ตฌ์ฒด ํด๋์ค๋ฅผ ํจํค์ง ๊ฒฝ๊ณ๋ฅผ ๋์ด, ์ฆ ๋ค๋ฅธ ํจํค์ง์ ๊ตฌ์ฒด ํด๋์ค๋ฅผ ์์ํ๋ ์ผ์ ์ํํ๋ค. ์๊ธฐํ์๋ฉด, ์ด ์ฑ ์์์ โ์์โ์ ํด๋์ค๊ฐ ๋ค๋ฅธ ํด๋์ค๋ฅผ ํ์ฅํ๋ ๊ตฌํ ์์์ ๋งํ๋ค. ์ด๋ฒ ์์ดํ ์์ ๋ ผํ๋ ๋ฌธ์ ๋ ํด๋์ค๊ฐ ์ธํฐํ์ด์ค๋ฅผ ๊ตฌํํ๊ฑฐ๋ ์ธํฐํ์ด์ค๊ฐ ๋ค๋ฅธ ์ธํฐํ์ด์ค๋ฅผ ํ์ฅํ๋ ์ธํฐ ํ์ด์ค ์์๊ณผ๋ ๋ฌด๊ดํ๋ค.
์์
์ ๊ฐ์ฒด ์งํฅ 4๊ฐ์ง ํน์ง์ค ํ๋๋ก์ ํด๋์ค ๊ธฐ๋ฐ์ ํ๋ก๊ทธ๋๋ฐ์์ ๋ฐฐ์ฐ๋ ๊ฐ๋
์ด๋ค.
ํด๋์ค ์์์ ํตํด ์์ ํด๋์ค๋ ๋ถ๋ชจ ํด๋์ค์ ์์์ ๋ฌผ๋ ค ๋ฐ๊ฒ ๋๋ฉฐ, ๋ถ๋ชจ ํด๋์ค์ ๋ค๋ฅธ ๋ถ๋ถ๋ง ์ถ๊ฐํ๊ฑฐ๋ ์ฌ์ ์ํจ์ผ๋ก์จ ๊ธฐ์กด ์ฝ๋๋ฅผ ์ฝ๊ฒ ํ์ฅํ ์ ์๋ค.
๊ทธ๋์ ์์ ๊ด๊ณ๋ฅผ is-a
๊ด๊ณ๋ผ๋ ํํํ๊ธฐ๋ ํ๋ค.
is-a๋ ์ผ์ข ์ ~์ด๋ค๋ผ๋ ์๋ฏธ์ด๋ค.
์ถ์ฒ : https://itwiki.kr/w/%EB%8D%B0%EC%9D%B4%ED%84%B0%EB%B2%A0%EC%9D%B4%EC%8A%A4_ISA_%EA%B4%80%EA%B3%84
class Mobile {
// ...
}
class Apple extends Mobile {
// ...
}
์์์ ๋ฐฉ๋ฒ์ ๋ํด ๊ฐ์ฒด์งํฅ์ ์ฌ์ค๊ณผ ์คํด์์ ๋ค์๊ณผ ๊ฐ์ด ์ค๋ช ํ๋ค๊ณ ํจ.
๐ฌ ์์์ ์๋ธํ์ดํ(subtyping)๊ณผ ์๋ธํด๋์ฑ(subclassing)์ ๋ ๊ฐ์ง ์ฉ๋๋ก ์ฌ์ฉ๋ ์ ์๋ค.
์๋ธํด๋์ค๊ฐ ์ํผํด๋์ค๋ฅผ ๋์ฒดํ ์ ์๋ ๊ฒฝ์ฐ ์ด๋ฅผ ์๋ธํ์ดํ์ด๋ผ๊ณ ํ๋ค. ์๋ธํด๋์ค๊ฐ ์ํผํด๋์ค๋ฅผ ๋์ฒดํ ์ ์๋ ๊ฒฝ์ฐ์๋ ์๋ธํด๋์ฑ์ด๋ผ๊ณ ํ๋ค. ์๋ธํ์ดํ
์ ์ค๊ณ์ ์ ์ฐ์ฑ์ด ๋ชฉํ์ธ ๋ฐ๋ฉด ์๋ธํด๋์ฑ
์ ์ฝ๋์ ์ค๋ณต ์ ๊ฑฐ์ ์ฌ์ฌ์ฉ์ด ๋ชฉ์ ์ด๋ค.
[์์์ ํตํ ์ฝ๋ ์ฌ์ฌ์ฉ]
์ฝ๋์ ์ฌ์ฌ์ฉ
์ด๋ ๋ฌด์์ผ๊น? ์ ์ด์ ์ฐ๋ฆฌ๊ฐ ํจ์(function)์ ๋ง๋ค์ด ์ฐ๋ ์ด์ ๊ฐ ๊ณตํต์ ์ผ๋ก ์ฌ์ฉ๋๋ ์ฝ๋๋ฅผ ๋ฌถ์ด ์ฌ์ฌ์ฉ์ ํตํด ์ฝ๋ ์ค๋ณต์ ์ค์ด๊ธฐ ์ํด์์ด๋ค. ๊ฐ์ฒด ์งํฅ ํ๋ก๊ทธ๋๋ฐ์์ ๊ณตํต์ ์ผ๋ก ์ฌ์ฉ๋๋ ์ฝ๋๊ฐ ์๋ค๋ฉด, ๋ถ๋ชจ ํด๋์ค์ ๋ฉ์๋ ํ๋ ๋ง๋ค์ด๋๊ณ ์์์ ํตํด ๋ถ๋ชจ์ ๊ฒ์ ๊ฐ์ ธ์ ์ฌ์ฉํ๋ค๋ ๊ธฐ๋ฒ์ผ๋ก ์ฝ๋์ ์ฌ์ฌ์ฉ์ด๋ผ๊ณ ๋งํ๋ ๊ฒ์ด๋ค.
๋ค๋ง, ์๋ฐํ ๋งํ๋ฉด ์์์ ๊ทธ์ ์ฝ๋ ์ฌ์ฌ์ฉ์ ์ํ ๊ธฐ๋ฒ์ด ์๋๋ผ๊ณ ํ๋ค.
์ผ๋ฐ์ ์ธ ํด๋์ค๊ฐ ์ด๋ฏธ ๊ตฌํ์ด ๋์ด ์๋ ์ํ์์ ๊ทธ๋ณด๋ค ์ข ๋ ๊ตฌ์ฒด์ ์ธ ํด๋์ค๋ฅผ ๊ตฌํํ๊ธฐ ์ํด ์ฌ์ฉ๋๋ ๊ธฐ๋ฒ์ด๋ฉฐ, ๊ทธ๋ก ์ธํด ์์ ํด๋์ค์ ์ฝ๋๋ฅผ ํ์ ํด๋์ค๊ฐ ์ฌ์ฌ์ฉ ํ ์ ์์ ๋ฟ์ด๋ค.
์ด์ฒ๋ผ '์ฌ๋' ์ด๋ผ๋ ๊ฐ์ฒด ์ฃผ์ ๋ ๊ฐ์ง๋ง, ์คํ์, ๊ณ ๋ฑํ์ ์ฒ๋ผ ์๋ก ๋ค๋ฅธ ์์ฑ์ด๋ ๊ธฐ๋ฅ๋ค์ ๊ฐ์ง๊ณ ์์๋, ์ด๋ฌํ ๊ตฌ์กฐ๋ฅผ ์์ ๊ด๊ณ๋ฅผ ํตํด ๋ ผ๋ฆฌ์ ์ผ๋ก ๊ฐ๋ ์ ์ผ๋ก ์ฐ๊ด ์ํค๋ ๊ฒ์ ์์์ด๋ผ ํ๋ค.
์์ ๊ด๊ณ๋ ์ปดํ์ผ ํ์
์ ๊ฒฐ์ ๋๊ณ ๊ณ ์ ๋๊ธฐ ๋๋ฌธ์ ์ฝ๋๋ฅผ ์คํํ๋ ๋์ค์ ๋ณ๊ฒฝํ ์ ์๋ค. ๋ฐ๋ผ์ ์ฌ๋ฌ ๊ธฐ๋ฅ์ ์กฐํฉํด์ผ ํ๋ ์ค๊ณ์ ์์์ ์ด์ฉํ๊ฒ ๋๋ค๋ฉด ๋ชจ๋ ์กฐํฉ๋ณ๋ก ํด๋์ค๋ฅผ ํ๋ํ๋ ์ถ๊ฐํด์ฃผ์ด์ผ ํ๋ค.
์ด๊ฒ์ ํด๋์ค ํญ๋ฐ ๋ฌธ์
๋ผ ํ๋ค.
๋๊ตฐ๋ค๋ Java8๋ถํฐ๋ ์ธํฐํ์ด์ค์ ๋ํดํธ ๋ฉ์๋ ๊ธฐ๋ฅ์ด ๋์ค๋ฉด์ ์ธํฐํ์ด์ค๋ด์์ ๋ก์ง ๊ตฌํ์ด ๊ฐ๋ฅํ์ฌ ์์์ ์ฅ์ ์ด ์ฝํ๋์๋ค๊ณ ํ ์ ์๋ค.
์๋ฐ์ ๊ฐ์ฒด ์งํฅ ํ๋ก๊ทธ๋๋ฐ์ ์ฒ์ ๋ฐฐ์ธ๋ ํด๋์ค์ ์์์ ๋ํด ๋ฐฐ์ฐ๊ธฐ ๋๋ฌธ์, ๋ง์น ์์์ด ์ฝ๋ ์ค๋ณต์ ์ ๊ฑฐํ๊ณ ํด๋์ค๋ฅผ ๋ฌถ๋ ๋คํ์ฑ
๋ ์ด์ฉํ ์ ์๊ณ ๋จ์ ๋ณด๋ค๋ ์ฅ์ ์ ๊ฐ์กฐํ๋ค ๋ณด๋ ๋ฌด๋ถ๋ณํ๊ฒ ์ฌ์ฉํ๋ ๊ฒฝ์ฐ๊ฐ ๋ง๋ค.
ํ์ง๋ง ํ์ , ์ดํํฐ๋ธ ์๋ฐ ๋ฑ์์
extends
๋ฅผ ์ง์ํ๋ ํธ์ด๋ฉฐ ํด๋์ค ์์์ ํด์ผํ ๋๋ ์ ๋ง ๊ฐ๋ ์ ์ผ๋ก ์ฐ๊ด ๊ด๊ณ๊ฐ ์์ ๋๋ง ํ๋ ์๋นํ ์ ํ์ ์ผ๋ก ์ ํ์ ์ผ๋ก ๋ค๋ค์ง๋ค.
์๋ธ ํด๋์ฑ์ด๋ ๊ด์ ์์ ๋ณธ ์์์ ๋ฌธ์ ์ ์ผ๋ก
์๋ธํด๋์ฑ
์ด๋ ์ฝ๋ ์ฌ์ฌ์ฉ ๋ชฉ์ ์ ์์
๋ค์์ ์ด๋ฏธ ์์ ์ ์ผ๋ก ๊ตฌํ๋ CircularBuffer
ํด๋์ค๋ฅผ ์์ํ์ฌ CircularQueue
์ CircularStack
์ ๊ตฌํํ๊ณ ์ ํ๋ ์์์ด๋ค. ์ด ์ฝ๋์์ ์์์ ํตํด ์ฝ๋๋ฅผ ์ฌ์ฌ์ฉํ ์ ์๋ค.
๋ค์์ Stack๊ณผ Queue ํด๋์ค๊ฐ List
ํด๋์ค๋ฅผ ์์๋ฐ์ ๋ ๋ฐ์ํ ์ ์๋ ๋ฆฌ์ค์ฝํ ์นํ ์์น(Liskov Substitution Principle, LSP) ์๋ฐ ๋ฌธ์ ๋ฅผ ๋ค๋ฃฌ ์์๋ฅผ ์ ๋ฆฌํ ๋ด์ฉ์
๋๋ค.
List ํด๋์ค ์ ์
์ฐ๋ฆฌ๋ List
ํด๋์ค๋ฅผ ์ฌ์ฉํ์ฌ ๋ฐ์ดํฐ๋ฅผ ๋ฐฐ์ด์ฒ๋ผ ์ ์ฅํ๊ณ , ์ผ์ชฝ์ด๋ ์ค๋ฅธ์ชฝ์ ๊ฐ์ ์ถ๊ฐํ๊ฑฐ๋ ์ ๊ฑฐํ ์ ์๋ ๋ฉ์๋๋ค์ ์ ๊ณตํ๋ค.
public class List {
private int[] elements;
// ๋งจ ์ฒ์์ ์์ ์ถ๊ฐ
public void pushLeft(int value) {
// ๊ตฌํ ์๋ต
}
// ๋งจ ๋์ ์์ ์ถ๊ฐ
public void push(int value) {
// ๊ตฌํ ์๋ต
}
// ์ฒซ ๋ฒ์งธ ์์ ์ ๊ฑฐ ํ ๋ฐํ
public int popLeft() {
// ๊ตฌํ ์๋ต
return 0; // ์์ ๋ฐํ๊ฐ
}
// ๋ง์ง๋ง ์์ ์ ๊ฑฐ ํ ๋ฐํ
public int pop() {
// ๊ตฌํ ์๋ต
return 0; // ์์ ๋ฐํ๊ฐ
}
}
์ด List
ํด๋์ค๋ ์ด๋ฏธ ์์ ์ ์ผ๋ก ๊ตฌํ๋ ์ํ๋ก, ์ด์ ์ด ํด๋์ค๋ฅผ ์์๋ฐ์ ์คํ๊ณผ ํ ์๋ฃ๊ตฌ์กฐ๋ฅผ ๊ตฌํํ๋ ค๊ณ ํ๋ค.
Stack๊ณผ Queue ํด๋์ค ์์
Stack
๊ณผ Queue
ํด๋์ค๋ List
ํด๋์ค๋ฅผ ์์๋ฐ์ ๊ฐ๊ฐ ์คํ๊ณผ ํ ์๋ฃ๊ตฌ์กฐ๋ก ๋์ํ๋๋ก ๊ตฌํ
public class Stack extends List {}
public class Queue extends List {}
์ด๋ ๊ฒ ํ๋ฉด Stack
๊ณผ Queue
๋ List
์ ๋ชจ๋ ๋ฉ์๋๋ฅผ ์์๋ฐ์ ์ฌ์ฌ์ฉํ ์ ์๋ค.
์คํ์ ํ์
์ ์ถ(FILO) ํน์ฑ์ ๊ฐ์ ธ์ผ ํ๋ค. ์ด๋ฅผ ์ํด push
์ pop
๋ฉ์๋๋ง์ ์ฌ์ฉํ๋ฉด ๋๋ค.
Stack stack = new Stack();
stack.push(1); // [1]
stack.push(2); // [1, 2]
stack.push(3); // [1, 2, 3]
stack.pop(); // [1, 2] => 3 ๋ฐํ
stack.push(4); // [1, 2, 4]
stack.pop(); // [1, 2] => 4 ๋ฐํ
ํ๋ ์ ์
์ ์ถ(FIFO) ํน์ฑ์ ๊ฐ์ ธ์ผ ํ๋ค. ์ด๋ฅผ ์ํด push
์ popLeft
๋ฉ์๋๋ง์ ์ฌ์ฉํ๋ฉด ๋๋ค.
Queue queue = new Queue();
queue.push(1); // [1]
queue.push(2); // [1, 2]
queue.push(3); // [1, 2, 3]
queue.popLeft(); // [2, 3] => 1 ๋ฐํ
queue.push(4); // [2, 3, 4]
queue.popLeft(); // [3, 4] => 2 ๋ฐํ
๐จ ๋ฌธ์ ์ : ์์ ํด๋์ค(๋ถ๋ชจ ํด๋์ค)๋ฅผ ์์๋ฐ์ ํ์ ํด๋์ค(์์ ํด๋์ค)๋ ์์ ํด๋์ค์์ ๊ธฐ๋ํ๋ ๋์์ ๊ทธ๋๋ก ์ ์งํด์ผ ํ๋ค๋ ์์น์ธ
๋ฆฌ์ค์ฝํ ์นํ ์์น
์๋ฐฐ
Stack
๊ณผ Queue
๋ List
์ฒ๋ผ ์ฌ์ฉ๋๋๋ผ๋ ๋ฌธ์ ๊ฐ ์์ด์ผ ํ๋ค. Stack
๊ณผ Queue
๊ฐ List
๋ฅผ ์์๋ฐ์์ผ๋ฏ๋ก, ๊ฐ ํด๋์ค๋ ๋ฌธ๋ฒ์ ์ผ๋ก List
ํ์
์ผ๋ก ๋ค๋ค์ง ์ ์๋ค.
List stack = new Stack();
List queue = new Queue();
๊ทธ๋ฌ๋ List
์ ๋ชจ๋ ๋ฉ์๋๋ฅผ ์์๋ฐ์ Stack
๊ณผ Queue
๋ ๋ณธ๋ ์ ๊ณตํ์ง ์์์ผ ํ ๋ฉ์๋๋ค ์ฆ, ๋ถํ์ํ ๋ฉ์๋๋ค(pushLeft
, popLeft
๋ฑ)๋ ์ฌ์ฉํ ์ ์๊ฒ ๋๋ค. ์ด๊ฒ์ ๊ฐ๊ฐ์ ์๋ฃ๊ตฌ์กฐ์ ๊ธฐ๋ณธ ํน์ฑ์ ๊นจ๋จ๋ฆด ์ ์๋ค.
์คํ ๊ฐ์ฒด์์ pushLeft
๋ popLeft
๋ฅผ ์ฌ์ฉํ ๊ฒฝ์ฐ, ํ์
์ ์ถ(FILO) ํน์ฑ์ด ๊นจ์ง๋ค.
List stack = new Stack();
stack.push(1); // [1]
stack.push(2); // [1, 2]
stack.push(3); // [1, 2, 3]
stack.pushLeft(4); // [4, 1, 2, 3] - ์์๊ฐ ๊นจ์ง
stack.pop(); // [4, 1, 2] => 3 ๋ฐํ
stack.popLeft(); // [1, 2] => 4 ๋ฐํ
ํ ๊ฐ์ฒด์์๋ pushLeft
๋ pop
์ ์ฌ์ฉํ ๊ฒฝ์ฐ, ์ ์
์ ์ถ(FIFO) ํน์ฑ์ด ๊นจ์ง๋ค.
List queue = new Queue();
queue.push(1); // [1]
queue.push(2); // [1, 2]
queue.push(3); // [1, 2, 3]
queue.pushLeft(4); // [4, 1, 2, 3] - ์์๊ฐ ๊นจ์ง
queue.pop(); // [4, 1, 2] => 3 ๋ฐํ
queue.popLeft(); // [1, 2] => 4 ๋ฐํ
์ด๋ ๋ฆฌ์ค์ฝํ ์นํ ์์น์ ์๋ฐฐํ๋ ์ฌ๋ก๋ก, ์ฝ๋์ ์ ์ง๋ณด์์ฑ๊ณผ ๊ฐ๋ ์ฑ์ ๋ฌธ์ ๊ฐ ๋ฐ์ํ ์ ์๋ค.
๐ข ์ฆ,
์๋ธ ํด๋์ฑ ๊ด์
์ ์์์ ํ์ ๋ค ์ฌ์ด์ ๊ด๊ณ์ ๋ํ ๊ณ ๋ ค ์์ด ์ค๋ก์ง ์ฝ๋ ์ฌ์ฌ์ฉ๋ง์ ๋ชฉ์ ์ผ๋ก ์์์ ์ฌ์ฉํ ๊ฒฝ์ฐ ๋ฐ์ํ ์ ์๋ ๋ฌธ์ ์ด๋ค.
์์์ผ๋ก ์ธํด Stack๊ณผ Queue์ ํธ์ถ๋์ด์๋ ์๋๋ ๋ฉ์๋๋ค์ด ๋ถํ์ํ๊ฒ ์๊ฒจ๋ฌ๊ธฐ ๋๋ฌธ์, ์ ํํ ๋งํ๋ฉด Stack๊ณผ Queue ํ์ ์ ๋ถํ์ํ ํผ๋ธ๋ฆญ ์ธํฐํ์ด์ค๋ค์ด ๊ณผํ๊ฒ ์์๋์๊ธฐ ๋๋ฌธ์ ๋ฐ์ํ ๋ฌธ์ ์ด๋ค
์ด์ฒ๋ผ ์ฝ๋๋ฅผ ์์๋ฐ์ Stack๊ณผ Queue๋ฅผ ๊ตฌํํ๋ ๊ฒ์ ์๋ชป๋ ์ค๊ณ์ด๋ค. Stack๊ณผ Queue์ ๋์์ ๋ค๋ฅด๊ธฐ ๋๋ฌธ์ ์์๋ณด๋ค๋ ๊ฐ๊ฐ์ ๋์์ ๊ตฌํํ ๋ณ๋์ ํด๋์ค๋ฅผ ๋ง๋ค์ด์ผ ํ๋ค.
๋ฆฌ์ค์ฝํ ์นํ์์น
์ด๋ ๊ฐ๋จํ ๋งํด "์์์ ํ ๋ ์๋ธํด๋์ฑ์ ๋์๊ณ ์๋ธํ์ดํ์ ํด์ผ ํ๋ค"๋ผ๋ ์์น
์๋ธํ์ดํ์ ๋ํด ์กฐ์ํธ(2019)๋ ์ค๋ธ์ ํธ์์ ๋ค์๊ณผ ๊ฐ์ด ์ค๋ช ํ๋ค.
๐ฌ "์์์ ์ฌ์ฉํ๋ ์ผ์ฐจ์ ์ธ ๋ชฉํ๋ ์ฝ๋ ์ฌ์ฌ์ฉ์ด ์๋๋ผ ํ์ ๊ณ์ธต์ ๊ตฌํํ๋ ๊ฒ์ด์ด์ผ ํ๋ค... ๋์ผํ ๋ฉ์์ง์ ๋ํด ์๋ก ๋ค๋ฅด๊ฒ ํ๋ํ ์ ์๋ ๋คํ์ ์ธ ๊ฐ์ฒด๋ฅผ ๊ตฌํํ๊ธฐ ์ํด์๋ ๊ฐ์ฒด์ ํ๋์ ๊ธฐ๋ฐ์ผ๋ก ํ์ ๊ณ์ธต์ ๊ตฌ์ฑํด์ผ ํ๋ค. ์์์ ๊ฐ์น๋ ์ด๋ฌํ ํ์ ๊ณ์ธต์ ๊ตฌํํ ์ ์๋ ์ฝ๊ณ ํธ์ํ ๋ฐฉ๋ฒ์ ์ ๊ณตํ๋ค๋ ๋ฐ ์๋ค."
์ฆ, ์๋ธ ํด๋์ฑ ๊ด์ ์ผ๋ก ์์ํ๋ฉด ๋ฌธ์ ๊ฐ ์๊ธด๋ค๋ ์ ์ ์๋ธํ์ดํ์์๋ ๋งํ๊ณ ์๋ ๊ฒ์ด๋ค.
์์ ํด๋์ค๊ฐ ์ด๋ป๊ฒ ๊ตฌํ๋๋๋์ ๋ฐ๋ผ ํ์ ํด๋์ค์ ๋์์ ์ด์์ด ์๊ธธ ์ ์๋ค.
์ฌ๊ธฐ์ ์บก์ํ๋, ๋จ์ํ private ๋ณ์๋ก Getter / Setter ๋ฅผ ์๊ธฐํ๋ ๊ฒ์ด ์๋๋ค.
์บก์ํ(์ ๋ณด ์๋)
์ ๊ฐ์ฒด๊ฐ ๋ด๋ถ์ ์ผ๋ก ๊ธฐ๋ฅ์ ์ด๋ป๊ฒ ๊ตฌํํ๋์ง๋ฅผ ๊ฐ์ถ๋ ๊ฒ์ ๋งํ๋ค. ๊ทธ๋์ ์ฐ๋ฆฌ๋ ํด๋์ค ์๋ฃํ์ ์ด์ฉํ ๋ ๋ด๋ถ ๋์์ ์ํ์์์ด ๋จ์ํ ๋ฉ์๋๋ง ๊ฐ๋ค ์ฐ๋ฉด ๋๋ค. ๋จ, ๋ด๋ถ ๋์์ ์ ํ์๊ฐ ์๋ค๋ ๋ง์ ์ ๋ขฐ์ฑ์ด ๋ณด์ฅ๋์ด์ผ ํ๋ค๋ ๋ง์ด๊ธฐ๋ ํ๋ค. ์บก์ํ๊ฐ ๊นจ์ง๊ฑด ์ด๋ฌํ์ ๋ขฐ์ฑ์ด ๊นจ์ง๊ฒ
์ด๋ผ๊ณ ๋ณด๋ฉด ๋๋ค.
์๋ชป๋ ์์์ ์
public class InstrumentedHashSet<E> extends HashSet<E> {
private int addCount = 0;
public InstrumentedHashSet() { }
@Override
public boolean add(E e) {
addCount++;
return super.add(e);
}
@Override
public boolean addAll(Collection<? extends E> c) {
addCount += c.size();
return super.addAll(c);
}
public int getAddCount() {
return addCount;
}
}
InstrumentedHashSet<String> s = new InstrumentedHashSet<>();
s.addAll(Arrays.asList("ํฑ", "ํํ", "ํ"));
System.out.println(s.getAddCount()); // ์์: 3, ์ค์ : 6
์ผ๋ฐ์ ์ผ๋ก ์ ์ฝ๋ ์คํ ํ addCount
๊ฐ 3์ด ๋ ๊ฒ์ด๋ผ ์์ํ ๊ฒ์ด๋ค. ํ์ง๋ง ์ค์ ๋ก๋ 6์ด๋ค. ์ด์ ๋ ๋ถ๋ชจ ํด๋์ค์ธ HashSet
์ addAll
๋ฉ์๋ ์์์ add
๋ฉ์๋๋ฅผ ํธ์ถํ๊ธฐ ๋๋ฌธ์ด๋ค.
public boolean addAll(@NotNull Collection<? extends E> c) {
boolean modified = false;
for (E e : c) {
if (add(e)) { // ๋ด๋ถ์์ ์์ฒด์ ์ผ๋ก add()๋ฅผ ๊ณ์ ํธ์ถํ๊ฑฐ์
modified = true;
}
}
return modified;
}
addAll
์ ํธ์ถํ๋ฉด ๋ด๋ถ์์add
๋ฅผ ํธ์ถํ๋๋ฐadd
๊ฐ ์์ ํด๋์ค์ add๋ฅผ ํธ์ถํ ์ค ์์์ง๋งInstrumentedHashSet
์add
๋ฅผ ํธ์ถํ๋ค.
์์์์ ๋ฌธ์ ๋ ๋ฉ์๋ ์ฌ์ ์ ์ ๋น์ฅ์ ํด๊ฒฐํ ์ ์์ผ๋, HashSet์ addAll
์ด add ๋ฉ์๋๋ฅผ ์ด์ฉํด ๊ตฌํํ์์ ๊ฐ์ ํ ํด๋ฒ์ด๋ผ๋ ํ๊ณ๋ฅผ ์ง๋๋ค. ์ด์ฒ๋ผ ์์ ์ ๋ค๋ฅธ ๋ถ๋ถ์ ์ฌ์ฉํ๋ ์๊ธฐ์ฌ์ฉ(self-use)
์ฌ๋ถ๋ ํด๋น ํด๋์ค์ ๋ด๋ถ ๊ตฌํ ๋ฐฉ์ ์ ํด๋นํ๋ฉฐ, ์๋ฐ ํ๋ซํผ ์ ๋ฐ์ ์ธ ์ ์ฑ
์ธ์ง, ๊ทธ๋์ ๋ค์ ๋ฆด๋ฆฌ์ค์์๋ ์ ์ง๋ ์ง๋ ์ ์ ์๋ค. ๋ฐ๋ผ์ ์ด๋ฐ ๊ฐ์ ์ ๊ธฐ๋ InstrumentedHashSet
๋ ๊นจ์ง๊ธฐ ์ฝ๋ค.
addAll
๋ฉ์๋๋ฅผ ๋ค๋ฅธ ์์ผ๋ก ์ฌ์ ์ํ ์๋ ์๋ค. ์ฃผ์ด์ง ์ปฌ๋ ์
์ ์ํํ๋ฉฐ ์์ ํ๋๋น add
๋ฉ์๋๋ฅผ ํ๋๋ง ํธ์ถํ๋ ๊ฒ์ด๋ค. ์กฐ๊ธ ๋์ ๋ฐฉ๋ฒ์ด์ง๋ง ์์ ํด๋์ค์ ๋ฉ์๋ ๋์์ ๋ค์ ๊ตฌํํ๋ ๊ฒ์ ์ด๋ ต๊ณ , ๋น์ฉ์ด ๋ ๋ค. ๋ํ ํ์ ํด๋์ค์์ ์ ๊ทผํ ์ ์๋ private ํ๋๋ฅผ ์จ์ผ ํ๋ค๋ฉด ์ด ๋ฐฉ์์ผ๋ก๋ ๊ตฌํ ์์ฒด๊ฐ ๋ถ๊ฐ๋ฅํ๋ค.
HashSet
์ ๋ด๋ถ ๊ตฌํ์ด addAll()
์์ add()
๋ฅผ ํธ์ถํ๋ค๋ ์ฌ์ค์ ์์กดํ๊ณ ์๋ค.๊ทธ๋ ๋ค๋ฉด ์์์์ ๋ฌธ์ ๋ ๋ค ๋ฉ์๋ ์ฌ์ ์ ์๋๊น ์๋ก์ด ๋ฉ์๋๋ฅผ ์ถ๊ฐํ๋ค๋ฉด?
์ด ๋ฐฉ์์ด ํจ์ฌ ์์ ํ ๊ฒ์ ๋ง์ง๋ง, ์ํ์ด ์ ํ ์๋ ๊ฒ์ ์๋๋ค. ๋ค์ ๋ฆด๋ฆฌ์ค์์ ์์ ํด๋์ค์ ์ ๋ฉ์๋๊ฐ ์ถ๊ฐ๋๋๋ฐ, ํํ ํ์ ํด๋์ค์ ์ถ๊ฐํ ๋ฉ์๋์ ์๊ทธ๋์ฒ๊ฐ ๊ฐ๊ณ ๋ฐํ ํ์ ์ ๋ค๋ฅด๋ค๋ฉด ์ฌ๋ฌ๋ถ์ ํด๋์ค๋ ์ปดํ์ผ์กฐ์ฐจ ๋์ง ์์ ์ ์๋ค.
์์์ ์ฝ๋๋ฅผ ์ฌ์ฌ์ฉํ๋ ๊ฐ๋ ฅํ ์๋จ์ด์ง๋ง, ํญ์ ์ต์ ์ ์๋๋ค
๋ถ๋ชจ ํด๋์ค์ ๋ด๋ถ ๋ณ๊ฒฝ์ด ์์ ํด๋์ค์ ์ํฅ์ ์ค ์ ์์ด ์ ์ฐ์ฑ์ด ์ ํ๋๋ค. ์์์ ํ๊ฒ ๋๋ฉด ๋ถ๋ชจ ํด๋์ค์ ์์ ํด๋์ค์ ๊ด๊ณ๊ฐ ์ปดํ์ผ ์์
์ ๊ด๊ณ๊ฐ ๊ฒฐ์ ๋์ด ๊ฒฐํฉ๋๊ฐ ๋น์ฐํ ๋์์ง์ ๋ฐ์ ์๋ค.
์๋ฅผ ๋ค์ด ํด๋์ค B๊ฐ ํด๋์ค A๋ฅผ ์์(extends) ํ๋ค๊ณ ํ๋ฉด, ์ฝ๋ ์คํ(๋ฐํ์) ์ค๊ฐ์ ํด๋์ค C๋ฅผ ์์ํ๋๋ก ๋ฐ๊ฟ์ ์๋ค. ์ฒ์ ์คํ๋๊ธฐ ์ ์ ๋ฏธ๋ฆฌ ๊ทธ๋ ๊ฒ ๊ฒฐ์ ๋์๊ธฐ ๋๋ฌธ์ด๋ค.
๋ง์น ์์์ ๋ถ๋ชจ์ ๊ฑฐ์ธ์ด๋ผ๋ ๋ง์ฒ๋ผ ๋ถ๋ชจ์ ์ ์ข์ ์ ์ ์์ํด๋์ค๋ค์ด ๋ค ๋ฎ๊ฒ ๋๋ค.
[๊ฒฐํจ ์์]
๋ถ๋ชจ ํด๋์ค์ ๊ฒฐํจ์ด ์์ ๋ ์์ ํด๋์ค๋ ๊ทธ ๊ฒฐํจ์ ๊ทธ๋๋ก ์์๋ฐ๊ฒ ๋๋ ์ํฉ์
๋๋ค.
class Vehicle {
private int speed;
public Vehicle(int speed) {
this.speed = speed;
}
// ๊ฒฐํจ์ด ์๋ ๋ฉ์๋: ์๋๊ฐ ์์์ผ ๋๋ ํ์ฉ
public void accelerate(int increment) {
speed += increment;
}
public int getSpeed() {
return speed;
}
}
class Car extends Vehicle {
public Car(int speed) {
super(speed);
}
// Car๋ ๋ณ๋์ ๊ฒฐํจ์ด ์์ผ๋ ๋ถ๋ชจ ํด๋์ค์ accelerate ๋ฉ์๋ ๊ฒฐํจ์ ๊ทธ๋๋ก ์์
}
public class Main {
public static void main(String[] args) {
Car car = new Car(50);
car.accelerate(-100); // ์๋๊ฐ ์์๊ฐ ๋ ์ ์๋ ๋ฌธ์ ๋ฐ์
System.out.println("Car speed: " + car.getSpeed()); // ์ถ๋ ฅ ๊ฒฐ๊ณผ๊ฐ ์์
}
}
์ ์ฝ๋์์ Vehicle ํด๋์ค์ accelerate ๋ฉ์๋์ ๊ฒฐํจ์ด ์์ด ์์ ์๋๊ฐ ํ์ฉ๋์ง๋ง, ์ด ๊ฒฐํจ์ด ์์ ํด๋์ค Car์๋ ๊ทธ๋๋ก ์ํฅ์ ๋ฏธ์น๋ค.
[๋ถ๋ชจ ํด๋์ค์ ์์ ํด๋์ค์ ๋์ ์์ ๋ฌธ์ ]
๋ถ๋ชจ ํด๋์ค๊ฐ ๋ณ๊ฒฝ๋ ๋ ์์ ํด๋์ค์ ํธ์ถ๋ถ๋ ๋ชจ๋ ์์ ํด์ผ ํด์ผ ํจ
์์์ ๋จ์ฉํ ๊ฒฝ์ฐ ํด๋์ค ํญ๋ฐ(class explosion) ๋ฌธ์ ๊ฐ ๋ฐ์ํ ์ ์๋ค.
์ฆ, ๊ธฐ๋ฅ์ ์ถ๊ฐํ๊ธฐ ์ํด ์์์ ๊ณ์ํ๋ค ๋ณด๋ฉด ํด๋์ค๊ฐ ๊ธ๊ฒฉํ ๋์ด๋๊ณ , ์๋ก ๋ณต์กํ๊ฒ ์ฝํ๊ฒ ๋์ด ๊ด๋ฆฌ๊ฐ ์ด๋ ค์์ง๋ค. ์ด๋ฅผ ์กฐํฉ์ ํญ๋ฐ(combinational explosion)์ด๋ผ๊ณ ๋ ๋ถ๋ฅธ๋ค.
์์
์ ์ปดํ์ผ ํ์์ ๊ฒฐ์ ๋๋ฏ๋ก, ์คํ ์ค์ ๋ณ๊ฒฝํ ์ ์๋ค. ๊ธฐ๋ฅ์ ์ถ๊ฐํ๊ฑฐ๋ ์์ ํ ๋๋ง๋ค ์๋ก์ด ํด๋์ค๋ฅผ ์์๋ฐ์ ์ถ๊ฐํด์ผ ํ๋ค.
์ด๋ฌํ ๋ฌธ์ ๋ฅผ ํผํ๊ธฐ ์ํด์๋ ์์ ๋์ ํฉ์ฑ(Composition)์ ์ฌ์ฉํ๋ ๊ฒ์ด ์ข์ต๋๋ค. ํฉ์ฑ์ ๊ธฐ์กด ๊ฐ์ฒด๋ฅผ ํฌํจํ๊ณ , ๊ทธ ๊ฐ์ฒด์ ๊ธฐ๋ฅ์ ์ถ๊ฐํ๋ ๋ฐฉ์์ผ๋ก ์์์ ๋ฌธ์ ๋ฅผ ํผํ ์ ์์ต๋๋ค.
์๋ฐ๋ ๋ค์ค ์์์ ์ง์ํ์ง ์๊ธฐ ๋๋ฌธ์ ํ๋์ ํด๋์ค๋ ์ค์ง ํ๋์ ๋ถ๋ชจ ํด๋์ค๋ง ์์๋ฐ์ ์ ์๋ค.
๋ค์ค ์์์ด ๋ถ๊ฐ๋ฅํ๊ธฐ ๋๋ฌธ์ ์์ ๊ณ์ธต์ ๋ณต์กํ๊ฒ ๋๋ ์ผ ํ๋ ์ํฉ์ด ๋ฐ์ํ ์ ์๋ค.
์ด๋ก ์ธํด ํด๋์ค ํญ๋ฐ ๋ฌธ์ ๊ฐ ๋์ฑ ์ฌํ๋ ์ ์๋ค. ๋ฐ๋ผ์, ์๋ฐ์์๋ ์ด๋ฐ ๋จ์ผ ์์์ ๋ฌธ์ ๋ฅผ ํด๊ฒฐํ๊ธฐ ์ํด ์ธํฐํ์ด์ค๋ฅผ ์ฌ์ฉํ์ฌ ๋ค์ค ๊ตฌํ์ ์ง์ํ๊ณ ์๋ค.
ํ๋์ ํด๋์ค๊ฐ ๋ค๋ฅธ ํด๋์ค์ ์ธ์คํด์ค๋ฅผ ํฌํจํ์ฌ, ๊ทธ ์ธ์คํด์ค์ ๋ฉ์๋๋ฅผ ํ์ฉํ๋ ๋ฐฉ์
ํฉ์ฑ
์ ๊ฐ์ฒด ๊ฐ์ ๊ด๊ณ๊ฐ ์์ง๊ด๊ณ๊ฐ ์๋ ์ํ ๊ด๊ณ๊ฐ ๋๋ค.
ํฉ์ฑ์ ๊ธฐ์กด ํด๋์ค๋ฅผ ์์์ ํตํ ํ์ฅํ๋ ๋์ ์, ํ๋๋ก ํด๋์ค์ ์ธ์คํด์ค๋ฅผ ์ฐธ์กฐํ๊ฒ ๋ง๋๋ ์ค๊ณ์ด๋ค. ์๋ฅผ ๋ค์ด ์๋ก ๊ด๋ จ์๋ ์ด์ง์ ์ธ ํด๋์ค์ ๊ด๊ณ์์, ํ ํด๋์ค๊ฐ ๋ค๋ฅธ ํด๋์ค์ ๊ธฐ๋ฅ์ ์ฌ์ฉํ์ฌ ๊ตฌํํด์ผ ํ๋ค๋ฉด ํฉ์ฑ์ ๋ฐฉ์์ ์ฌ์ฉํ๋ค๊ณ ๋ณด๋ฉด ๋๋ค.
์ปดํจํฐ(Computer)์ ๋ชจ๋ํฐ(Monitor)์ ๊ด๊ณ๋ฅผ ์๋ก ๋ค์ด๋ณด๊ฒ ๋ค. ์ปดํจํฐ๋ ๋ชจ๋ํฐ๊ฐ ํ์ํ์ง๋ง, ๋ชจ๋ํฐ๋ฅผ ์์๋ฐ์ ํ์๋ ์๋ค. ๋์ ๋ชจ๋ํฐ๋ฅผ ํฉ์ฑํ์ฌ ์ฌ์ฉํ๋ ๊ฒ์ด ๋ ์ ํฉํ๋ค.
// Computer ํด๋์ค
class Computer {
Monitor monitor; // ํ๋๋ก Monitor ํด๋์ค ๋ณ์๋ฅผ ๊ฐ๋๋ค (Has-A ๊ด๊ณ)
Computer(Monitor monitor) {
this.monitor = monitor; // ์์ฑ์ ์ด๊ธฐํ ์ Monitor ์ธ์คํด์ค๋ฅผ ๋ฐ์
}
void display() {
System.out.printf("%s ๋ชจ๋ํฐ๋ก ํ๋ฉด ์ถ๋ ฅ ์ค...\n", monitor.getMonitorType());
}
void turnOff() {
System.out.printf("%s ๋ชจ๋ํฐ๋ฅผ ๋๋๋ค...\n", monitor.getMonitorType());
}
}
// Monitor ํด๋์ค
class Monitor {
String monitorType; // ๋ชจ๋ํฐ ์ข
๋ฅ (์: LCD, LED)
Monitor(String type) {
this.monitorType = type;
}
String getMonitorType() {
return this.monitorType;
}
}
// Main ํด๋์ค
public class Main {
public static void main(String[] args) {
// LCD ๋ชจ๋ํฐ๊ฐ ์ฐ๊ฒฐ๋ ์ปดํจํฐ
Computer lcdComputer = new Computer(new Monitor("LCD"));
lcdComputer.display(); // LCD ๋ชจ๋ํฐ๋ก ํ๋ฉด ์ถ๋ ฅ ์ค...
// LED ๋ชจ๋ํฐ๊ฐ ์ฐ๊ฒฐ๋ ์ปดํจํฐ
Computer ledComputer = new Computer(new Monitor("LED"));
ledComputer.display(); // LED ๋ชจ๋ํฐ๋ก ํ๋ฉด ์ถ๋ ฅ ์ค...
lcdComputer.turnOff(); // LCD ๋ชจ๋ํฐ๋ฅผ ๋๋๋ค...
ledComputer.turnOff(); // LED ๋ชจ๋ํฐ๋ฅผ ๋๋๋ค...
}
}
ํฉ์ฑ
์ ์๋ก ์ปดํจํฐ๋ ๋ชจ๋ํฐ๋ฅผ ํ์๋ก ํ์ง๋ง, ๋ชจ๋ํฐ๋ฅผ ์์ํ์ง ์๊ณ ์ธ์คํด์ค๋ก ์ฐธ์กฐํ์ฌ ๊ธฐ๋ฅ์ ์ฌ์ฉํ๋ค.์์ ์ด๊ธฐํ ์ฝ๋์์ ๋ณผ์ ์๋ฏ์ด, ๊ธฐ์กด ํด๋์ค๋ฅผ ํ์ฅํ๋ ๋์ , ์๋ก์ด ํด๋์ค๋ฅผ ๋ง๋ค๊ณ private ํ๋๋ก ๊ธฐ์กด ํด๋์ค์ ์ธ์คํด์ค๋ฅผ ์ฐธ์กฐํ๊ฒ ํ ๊ฒ์ด๋ค.
์์์ ๋ฌธ์ ์ ๋์๋ฒ์ธ ํฉ์ฑ์ ๊ธฐ๋ฅ์ด ํ์ํ๋ค๊ณ ํด์ ๋ฌด์กฐ๊ฑด ์์ํ์ง๋ง๊ณ , ๋ฐ๋ก ํด๋์ค ์ธ์คํด์ค ๋ณ์์ ์ ์ฅํ์ฌ ๊ฐ์ ธ๋ค ์ด๋ค๋ ์๋ฆฌ์ด๋ค.
์ ํด๋์ค์ ์ธ์คํด์ค ๋ฉ์๋๋ค์ (private ํ๋๋ก ์ฐธ์กฐํ๋) ๊ธฐ์กด ํด๋์ค์ ๋์ํ๋ ๋ฉ์๋๋ฅผ ํธ์ถ ํด ๊ทธ ๊ฒฐ๊ณผ๋ฅผ ๋ฐํํ๋ค. ์ด ๋ฐฉ์์ ์ ๋ฌ(forwarding)์ด๋ผ ํ๋ฉฐ, ์ ํด๋์ค์ ๋ฉ์๋๋ค์ ์ ๋ฌ ๋ฉ์๋(forwarding method)๋ผ ๋ถ๋ฅธ๋ค.
๊ทธ ๊ฒฐ๊ณผ ์๋ก์ด ํด๋์ค๋ ๊ธฐ์กด ํด๋์ค์ ๋ด๋ถ ๊ตฌํ ๋ฐฉ์์ ์ํฅ์์ ๋ฒ์ด๋๋ฉฐ, ์ฌ์ง์ด ๊ธฐ์กด ํด๋์ค์ ์๋ก์ด ๋ฉ์๋๊ฐ ์ถ๊ฐ๋๋๋ผ๋ ์ ํ ์ํฅ๋ฐ์ง ์๋๋ค.
์์ ๋์ ์ปดํฌ์ง์
(Composition)์ ์ฌ์ฉํ์ฌ ๊ธฐ์กด Set
์ธ์คํด์ค๋ฅผ ๊ฐ์ธ๋ ๋ํผ ํด๋์ค(Wrapper Class)๋ฅผ ๋ง๋ค์ด๊ฐ์.
public class InstrumentedSet<E> implements Set<E> {
private final Set<E> set;
private int addCount = 0;
public InstrumentedSet(Set<E> set) {
this.set = set;
}
@Override
public boolean add(E e) {
addCount++;
return set.add(e);
}
@Override
public boolean addAll(Collection<? extends E> c) {
addCount += c.size();
return set.addAll(c);
}
public int getAddCount() {
return addCount;
}
// ๋๋จธ์ง Set ์ธํฐํ์ด์ค ๋ฉ์๋๋ค์ set ์ธ์คํด์ค์ ์์
@Override
public int size() {
return set.size();
}
@Override
public boolean isEmpty() {
return set.isEmpty();
}
// ... ๊ธฐํ ๋ฉ์๋๋ค๋ ๋์ผํ๊ฒ ์์
}
์ค๋ช :
InstrumentedSet
์ Set
์ธํฐํ์ด์ค๋ฅผ ๊ตฌํํ๊ณ , ๋ด๋ถ์ ์ค์ ์์
์ ์ํํ Set
์ธ์คํด์ค๋ฅผ ๊ฐ์ง๋ค.set
๊ฐ์ฒด์ ์์
์ ์์ํ๋ค.add()
์ addAll()
๋ฉ์๋์์ addCount
๋ฅผ ์ ํํ๊ฒ ์ฆ๊ฐ์ํฌ ์ ์๋ค.์ฌ์ฉ ์์:
Set<String> s = new InstrumentedSet<>(new HashSet<>());
s.addAll(Arrays.asList("ํฑ", "ํํ", "ํ"));
System.out.println(((InstrumentedSet<String>) s).getAddCount()); // ์ถ๋ ฅ: 3
์์ ๋ฉ์๋๋ฅผ ์ผ์ผ์ด ์์ฑํ๋ ๋์ , ์ฌ์ฌ์ฉ ๊ฐ๋ฅํ ํฌ์๋ฉ ํด๋์ค๋ฅผ ๋ง๋ค์ด์ ์ค๋ณต ์ฝ๋๋ฅผ ์ค์ผ ์ ์๋ค.
public class ForwardingSet<E> implements Set<E> {
protected final Set<E> s;
public ForwardingSet(Set<E> s) {
this.s = s;
}
@Override
public boolean add(E e) { return s.add(e); }
@Override
public boolean addAll(Collection<? extends E> c) { return s.addAll(c); }
// ๋๋จธ์ง ๋ฉ์๋๋ค๋ ๋์ผํ๊ฒ s์ ์์
@Override
public int size() { return s.size(); }
@Override
public boolean isEmpty() { return s.isEmpty(); }
// ... ๊ธฐํ ๋ฉ์๋๋ค๋ ๋์ผํ๊ฒ ์์
}
์ด์ InstrumentedSet
์ ForwardingSet
์ ์์๋ฐ์ ํ์ํ ๊ธฐ๋ฅ๋ง ์ถ๊ฐํ๋ฉด ๋จ
public class InstrumentedSet<E> extends ForwardingSet<E> {
private int addCount = 0;
public InstrumentedSet(Set<E> s) {
super(s);
}
@Override
public boolean add(E e) {
addCount++;
return super.add(e);
}
@Override
public boolean addAll(Collection<? extends E> c) {
addCount += c.size();
return super.addAll(c);
}
public int getAddCount() {
return addCount;
}
}
InstrumentedSet
์ HashSet
์ ๋ชจ๋ ๊ธฐ๋ฅ์ ์ ์ํ Set
์ธํฐํ์ด์ค๋ฅผ ํ์ฉํด ์ค๊ณ๋์ด ๊ฒฌ๊ณ ํ๊ณ ์์ฃผ ์ ์ฐํ๋ค. ๊ตฌ์ฒด์ ์ผ๋ก๋ Set ์ธํฐํ์ด์ค๋ฅผ ๊ตฌํํ๊ณ , Set์ ์ธ์คํด์ค๋ฅผ ์ธ์๋ก ๋ฐ๋ ์์ฑ์๋ฅผ ํ๋ ์ ๊ณตํ๋ค. ์์์ Set์ ๊ณ์ธก ๊ธฐ๋ฅ์ ๋ง์์ด ์๋ก์ด Set์ผ๋ก ๋ง๋๋ ๊ฒ์ด ์ด ํด๋์ค์ ํต์ฌ์ด๋ค. ์ด ์ปดํฌ์ง์
๋ฐฉ์์ ํ ๋ฒ๋ง ๊ตฌํํด๋๋ฉด ์ด๋ ํ Set ๊ตฌํ์ฒด๋ผ๋ ๊ณ์ธกํ ์ ์์ผ๋ฉฐ, ๊ธฐ์กด ์์ฑ์๋ค๋ ํจ๊ป ์ฌ์ฉํ ์ ์๋ค.
Set<Instant> times = new InstrumentedSet<>(new TreeSet<>(cmp));
Set<E> s = new InstrumentedSet<>(new HashSet<>(INIT_CAPACITY));
๋ค๋ฅธ Set ์ธ์คํด์ค๋ฅผ ๊ฐ์ธ๊ณ ์๋ค๋ ๋ป์์ InstrumentedSet
๊ฐ์ ํด๋์ค๋ฅผ ๋ํผ ํด๋์ค๋ผ ํ๋ฉฐ, ๋ค๋ฅธ Set์ ๊ณ์ธก ๊ธฐ๋ฅ์ ๋ง์์ด๋ค๋ ๋ป์์ ๋ฐ์ฝ๋ ์ดํฐ ํจํด์ด๋ผ๊ณ ํ๋ค. ์ปดํฌ์ง์
๊ณผ ์ ๋ฌ์ ์กฐํฉ์ ๋์ ์๋ฏธ๋ก ์์(delegation)์ด๋ผ๊ณ ๋ถ๋ฅธ๋ค.
์์์ ๋ฐ๋์ ํ์ ํด๋์ค๊ฐ ์์ ํด๋์ค์ '์ง์ง' ํ์ ํ์ ์ธ ์ํฉ์์๋ง ์ฐ์ฌ์ผ ํ๋ค. ๋ค๋ฅด๊ฒ ๋งํ๋ฉด, ํด๋์ค B๊ฐ ํด๋์ค A์
is-a
๊ด๊ณ์ผ ๋๋ง ํด๋์ค A๋ฅผ ์์ํด์ผ ํ๋ค.
์ปดํฌ์ง์ ์ ์จ์ผ ํ ์ํฉ์์ ์์์ ์ฌ์ฉํ๋ ๊ฑด ๋ด๋ถ ๊ตฌํ์ ๋ถํ์ํ๊ฒ ๋ ธ์ถํ๋ ๊ผด์ด๋ค. ๊ทธ ๊ฒฐ๊ณผ API๊ฐ ๋ด๋ถ ๊ตฌํ์ ๋ฌถ์ด๊ณ ๊ทธ ํด๋์ค์ ์ฑ๋ฅ๋ ์์ํ ์ ํ๋๋ค. ๋ ์ฌ๊ฐํ ๋ฌธ์ ๋ ํด๋ผ์ด์ธํธ๊ฐ ๋ ธ์ถ๋ ๋ด๋ถ์ ์ง์ ์ ๊ทผํ ์ ์๋ค๋ ์ ์ด๋ค.
๋ํผ ํด๋์ค๋ ๋จ์ ์ด ๊ฑฐ์ ์๋ค. ํ ๊ฐ์ง, ๋ํผ ํด๋์ค๊ฐ ์ฝ๋ฐฑ(callback) ํ๋ ์์ํฌ์๋ ์ด์ธ๋ฆฌ์ง ์๋๋ค๋ ์ ๋ง ์ฃผ์ํ๋ฉด ๋๋ค.
์ฝ๋ฐฑ ํ๋ ์์ํฌ์์ ๋ ์๊ธฐ ์์ ์ ์ฐธ์กฐ๋ฅผ ๋ค๋ฅธ ๊ฐ์ฒด์ ๋๊ฒจ์ ๋ค์ ํธ์ถ(์ฝ๋ฐฑ) ๋ ์ฌ์ฉํ๋๋ก ํ๋ค. ๋ด๋ถ ๊ฐ์ฒด๋ ์์ ์ ๊ฐ์ธ๊ณ ์๋ ๋ํผ์ ์กด์ฌ๋ฅผ ๋ชจ๋ฅด๋ ๋์ ์์ (this)์ ์ฐธ์กฐ๋ฅผ ๋๊ธฐ๊ณ , ์ฝ๋ฐฑ ๋๋ ๋ํผ๊ฐ ์๋ ๋ด๋ถ ๊ฐ์ฒด๋ฅผ ํธ์ถํ๊ฒ ๋๋ค. ์ด๋ฅผ SELF ๋ฌธ์
๋ผ๊ณ ํ๋ค.
์ ๋ฌ ๋ฉ์๋๊ฐ ์ฑ๋ฅ์ ์ฃผ๋ ์ํฅ์ด๋ ๋ํผ ๊ฐ์ฒด๊ฐ ๋ฉ๋ชจ๋ฆฌ ์ฌ์ฉ๋์ ์ฃผ๋ ์ํฅ์ ๊ฑฑ์ ํ๋ ์ฌ๋๋ ์์ง๋ง, ์ค์ ์์๋ ๋ ๋ค ๋ณ๋ค๋ฅธ ์ํฅ์ด ์๋ค๊ณ ๋ฐํ์ก๋ค. ์ ๋ฌ ๋ฉ์๋๋ค์ ์์ฑํ๋ ๊ฒ ์ฌ์ฌ์ฉํ ์ ์๋ ์ ๋ฌ ํด๋์ค๋ฅผ ์ธํฐ ํ์ด์ค๋น ํ๋์ฉ๋ง ๋ง๋ค์ด๋ ๋ฉด ์ํ๋ ๊ธฐ๋ฅ์ ๋ง์์ฐ๋ ์ ๋ฌ ํด๋์ค๋ค์ ์์ฃผ ์์ฝ๊ฒ ๊ตฌํํ ์ ์๋ค.
ํฉ์ฑ(Composition)์ ์ฌ์ฉํ๋ ์ด์ ๋ ์ ์ฐ์ฑ๊ณผ ์ฌ์ฌ์ฉ์ฑ์ ๋์ด๊ธฐ ์ํด์์ ๋๋ค. ์์์ ๋นํด ํฉ์ฑ์ ๋ค์๊ณผ ๊ฐ์ ์ด์ ์ด ์๋ค.
์์์์๋ ๊ฐ์ฒด ๊ฐ์ ๊ด๊ณ๊ฐ ๊ณ ์ ๋์ง๋ง, ํฉ์ฑ์์๋ ๋ ์ ์ฐํ๊ฒ ๊ฐ์ฒด๋ฅผ ๊ตฌ์ฑํ ์ ์๋ค.
โ ์์ ์์ (์์์ผ๋ก ๊ณ ์ ๋ ๊ด๊ณ)
// ๋ถ๋ชจ ํด๋์ค: Animal
class Animal {
public void eat() {
System.out.println("This animal is eating.");
}
}
// ์์ ํด๋์ค: Dog
class Dog extends Animal {
public void bark() {
System.out.println("The dog is barking.");
}
}
public class Main {
public static void main(String[] args) {
Dog dog = new Dog();
dog.eat(); // ์์๋ ๋ฉ์๋: Dog๊ฐ Animal์ eat ๋ฉ์๋๋ฅผ ์ฌ์ฉ
dog.bark(); // Dog ํด๋์ค์ ๋ฉ์๋
}
}
์ ์ฝ๋๋ Dog ํด๋์ค๊ฐ Animal ํด๋์ค๋ฅผ ์์ํ๋ฏ๋ก, Dog ๊ฐ์ฒด๋ Animal์ ๋ชจ๋ ๋ฉ์๋๋ฅผ ์๋์ผ๋ก ์์๋ฐ๋๋ค. ํ์ง๋ง ๊ด๊ณ๊ฐ ๊ณ ์ ๋์ด ๋ณ๊ฒฝํ๊ธฐ ์ด๋ ต๋ค.
โญํฉ์ฑ ์์ (์ ์ฐํ ๊ด๊ณ)
// ๋
๋ฆฝ์ ์ธ ๊ธฐ๋ฅ ํด๋์ค: SoundMaker
class SoundMaker {
public void makeSound(String sound) {
System.out.println(sound);
}
}
// ํฉ์ฑ์ ์ด์ฉํ Dog ํด๋์ค
class Dog {
private SoundMaker soundMaker; // Dog ํด๋์ค๋ SoundMaker๋ฅผ ์ฌ์ฉ (has-a ๊ด๊ณ)
public Dog() {
this.soundMaker = new SoundMaker();
}
public void bark() {
soundMaker.makeSound("The dog is barking.");
}
public void eat() {
System.out.println("The dog is eating.");
}
}
public class Main {
public static void main(String[] args) {
Dog dog = new Dog();
dog.bark(); // ํฉ์ฑ์ ์ด์ฉํ์ฌ ์๋ฆฌ๋ฅผ ๋ง๋ฆ
dog.eat(); // ๋
๋ฆฝ์ ์ธ Dog์ ๋ฉ์๋
}
}
์ฌ๊ธฐ์๋ Dog ํด๋์ค๊ฐ SoundMaker ๊ฐ์ฒด๋ฅผ ์กฐ๋ฆฝ(ํฉ์ฑ)ํ์ฌ ๋ ์ ์ฐํ๊ฒ ๋์์ ์ ์
์๋ฐ๋ ๋ค์ค ์์์ ์ง์ํ์ง ์์ง๋ง, ํฉ์ฑ์ ์ฌ์ฉํ๋ฉด ์ฌ๋ฌ ๊ฐ์ฒด๋ฅผ ํฉ์ฑํ์ฌ ๋ค์ค ์์๊ณผ ์ ์ฌํ ํจ๊ณผ๋ฅผ ์ป์ ์ ์๋ค.
โญ ํฉ์ฑ ์์ (๋ค์ค ์์ ๋์ฒด)
// ๋
๋ฆฝ์ ์ธ ๊ธฐ๋ฅ ํด๋์ค: Engine
class Engine {
public void start() {
System.out.println("Engine is starting...");
}
}
// ๋
๋ฆฝ์ ์ธ ๊ธฐ๋ฅ ํด๋์ค: GPS
class GPS {
public void activate() {
System.out.println("GPS is activated.");
}
}
// Car ํด๋์ค๊ฐ Engine๊ณผ GPS๋ฅผ ํฉ์ฑ
class Car {
private Engine engine; // Car๋ Engine์ ๊ฐ์ง (has-a)
private GPS gps; // Car๋ GPS๋ฅผ ๊ฐ์ง (has-a)
public Car() {
this.engine = new Engine();
this.gps = new GPS();
}
public void drive() {
engine.start();
gps.activate();
System.out.println("Car is driving.");
}
}
public class Main {
public static void main(String[] args) {
Car car = new Car();
car.drive(); // Car๋ Engine๊ณผ GPS ๊ธฐ๋ฅ์ ๋ชจ๋ ์ฌ์ฉํ ์ ์์
}
}
์ ์ฝ๋์์๋ Car๊ฐ Engine๊ณผ GPS ๋ ๊ฐ์ฒด๋ฅผ ํฉ์ฑํ์ฌ ๋ค์ค ์์ ์์ด ๋ ๊ฐ์ฒด์ ๊ธฐ๋ฅ์ ๋ชจ๋ ์ฌ์ฉํ ์ ์์ต๋๋ค.
์์์ ๋ถ๋ชจ ํด๋์ค์ ์ธ๋ถ ๊ตฌํ์ ์์กดํ์ง๋ง,
ํฉ์ฑ
์ ๊ฐ์ฒด์ ํ๋์ ์์ํจ์ผ๋ก์จ ๋ ๋ ๋ฆฝ์ ์ธ ๊ด๊ณ๋ฅผ ์ ๊ณตํ๋ค.
โ์์์ ๋ฌธ์ ์์
// ๋ถ๋ชจ ํด๋์ค: Beverage (์๋ฃ)
class Beverage {
public void drink() {
System.out.println("Drinking a beverage.");
}
}
// ์์ ํด๋์ค: Juice
class Juice extends Beverage {
public void addIce() {
System.out.println("Adding ice to the juice.");
}
}
public class Main {
public static void main(String[] args) {
Juice juice = new Juice();
juice.drink(); // ์์๋ ๋ฉ์๋: Juice๊ฐ Beverage์ drink ๋ฉ์๋๋ฅผ ์ฌ์ฉ
juice.addIce();
}
}
์ด ์ฝ๋์์ ๋ง์ฝ Beverage
ํด๋์ค์ ๋ณ๊ฒฝ์ด ์๊ธฐ๋ฉด Juice
ํด๋์ค์๋ ์ํฅ์ ๋ฏธ์นฉ๋๋ค. ์ด๋ ๋ถ๋ชจ ํด๋์ค์ ์์กดํ๋ ๋ฌธ์ ๋ฅผ ์ผ๊ธฐํ ์ ์๋ค.
โญ ํฉ์ฑ์ผ๋ก ํด๊ฒฐ
// ๋
๋ฆฝ์ ์ธ ๊ธฐ๋ฅ ํด๋์ค: IceMaker
class IceMaker {
public void addIce() {
System.out.println("Ice is added.");
}
}
// Juice ํด๋์ค๊ฐ IceMaker๋ฅผ ํฉ์ฑํ์ฌ ์ฌ์ฉ
class Juice {
private IceMaker iceMaker; // Juice๋ IceMaker๋ฅผ ํฉ์ฑ (has-a)
public Juice() {
this.iceMaker = new IceMaker();
}
public void drink() {
System.out.println("Drinking juice.");
}
public void addIce() {
iceMaker.addIce(); // IceMaker ๊ฐ์ฒด์ ๊ธฐ๋ฅ์ ์์
}
}
public class Main {
public static void main(String[] args) {
Juice juice = new Juice();
juice.drink();
juice.addIce(); // Juice๋ IceMaker ๊ฐ์ฒด์ ๋ฉ์๋๋ฅผ ํธ์ถํจ
}
}
์ด ๋ฐฉ์์ Juice๊ฐ IceMaker์ ๋ด๋ถ ๋์์ ์์กดํ์ง ์๊ธฐ ๋๋ฌธ์ ๋ ๋ ๋ฆฝ์ ์ด๊ณ ์ ์ฐํ๊ฒ ์ค๊ณํ ์ ์๋ค.
์์
์ ๋ถ๋ชจ ํด๋์ค์ ๋ชจ๋ public ๋ฉ์๋๋ฅผ ์์ ํด๋์ค์ ๊ณต๊ฐํ๋ ๋ฐ๋ฉด, ํฉ์ฑ์ ํ์ํ ๋ฉ์๋๋ง ๋ ธ์ถํ ์ ์๋ค.
โ ์์์์์ ๋ฌธ์
class Vector {
public void addElement(String element) {
System.out.println("Element added to vector: " + element);
}
}
class Stack extends Vector {
public void push(String element) {
addElement(element);
}
public void pop() {
System.out.println("Element removed from stack.");
}
}
public class Main {
public static void main(String[] args) {
Stack stack = new Stack();
stack.push("item");
stack.addElement("another item"); // ๋ถํ์ํ ๋ถ๋ชจ ํด๋์ค ๋ฉ์๋๊ฐ ๋
ธ์ถ๋จ
stack.pop();
}
}
์ด ์ฝ๋์์๋ Stack
ํด๋์ค์์ ๋ถํ์ํ addElement
๋ฉ์๋๊ฐ ๋
ธ์ถ๋์ด ์๋ชป๋ ์ฌ์ฉ์ ํ์ฉํ๊ฒ ๋๋ค.
โญ ํฉ์ฑ์ผ๋ก ์บก์ํ
// Vector์ ๋์ผํ ๊ธฐ๋ฅ์ ๊ฐ์ง ํด๋์ค: ListManager
class ListManager {
public void addElement(String element) {
System.out.println("Element added to list: " + element);
}
}
// Stack์ ListManager๋ฅผ ํฉ์ฑํ์ฌ ํ์ํ ๋ฉ์๋๋ง ๋
ธ์ถ
class Stack {
private ListManager listManager; // Stack์ ListManager๋ฅผ ํฉ์ฑ (has-a)
public Stack() {
this.listManager = new ListManager();
}
public void push(String element) {
listManager.addElement(element); // ํ์ํ ๊ธฐ๋ฅ๋ง ์ฌ์ฉ
}
public void pop() {
System.out.println("Element removed from stack.");
}
}
public class Main {
public static void main(String[] args) {
Stack stack = new Stack();
stack.push("item");
stack.pop();
// stack.addElement()๋ ํธ์ถํ ์ ์์
}
}
์ฌ๊ธฐ์ Stack
์ ListManager
์ ๋ด๋ถ ๋์ ์ค ํ์ํ ๋ฉ์๋๋ง ๋
ธ์ถํ์ฌ ์ฌ์ฉํ๋ฉฐ, ๋ถํ์ํ ์ธ๋ถ ์ฌํญ์ ์จ๊ธด๋ค.
ํฉ์ฑ
์ ์ฌ์ฉํ๋ฉด ๊ฐ ๊ฐ์ฒด๋ ๋
๋ฆฝ์ ์ผ๋ก ๊ด๋ฆฌ๋๋ฉฐ, ๋ณ๊ฒฝ์ ๋ ๊ฐํ ์ค๊ณ๋ฅผ ํ ์ ์๋ค.ํผ์ฉํด์ ์ฐ๋ ๊ฒฝ์ฐ๊ฐ ๋๋ถ๋ถ์ด๋ผ๊ณ ํจ.. ํฉ์ฑ์ด๋ผ๊ณ ํ๋ฉด ์ปดํฌ์ง์ ์ด๋ผ๊ณ ์๊ฐํด๋ ๋ฌด๋ฐฉํ ๋ฏ ํ๋ค.
์ปดํฌ์ง์ (Composition)๊ณผ ํฉ์ฑ(Aggregation)์ ๊ฐ์ฒด์งํฅ ํ๋ก๊ทธ๋๋ฐ์์ ๊ฐ์ฒด ๊ฐ์ ๊ด๊ณ๋ฅผ ๋ํ๋ผ ๋ ์ฌ์ฉํ๋ ์ค์ํ ๊ฐ๋ ๋ค์ด๋ค. ๋ ๊ฐ๋ ์ ์๋ก ์ ์ฌํ์ง๋ง ์ค์ํ ์ฐจ์ด์ ์ด ์์ผ๋ฉฐ, ๊ฐ๊ฐ์ ๊ฒฝ์ฐ์ ๋ง๋ ์ ์ ํ ์ฌ์ฉ ๋ฐฉ๋ฒ์ด ์๋ค.
์์ ์ฝ๋:
class Car {
private Engine engine;
Car() {
this.engine = new Engine(); // ์์ง์ ์ง์ ์ด๊ธฐํ
}
void start() {
engine.run();
}
}
class Engine {
void run() {
System.out.println("Engine is running...");
}
}
Car
๋ Engine
์ ํฌํจํ๊ณ ์์ผ๋ฉฐ, Car
๊ฐ ์์ด์ง๋ฉด Engine
๋ ์๋ฏธ๋ฅผ ์์ต๋๋ค. ์ด๋ ์ปดํฌ์ง์
์ ์ ํ์ ์ธ ์์์ ์ฝ๋:
class School {
private Student student;
School(Student student) {
this.student = student; // ์ธ๋ถ์์ ๊ฐ์ฒด๋ฅผ ์ฃผ์
๋ฐ์
}
void educate() {
student.study();
}
}
class Student {
void study() {
System.out.println("Student is studying...");
}
}
School
์ Student
๋ฅผ ์ฐธ์กฐํ๊ณ ์์ง๋ง, Student
๊ฐ์ฒด๋ School
์ด ์์ด์ ธ๋ ๋
๋ฆฝ์ ์ผ๋ก ์กด์ฌํ ์ ์์ต๋๋ค. ์ด๋ ํฉ์ฑ์ ์ ํ์ ์ธ ์ํญ๋ชฉ | ์ปดํฌ์ง์ (Composition) | ํฉ์ฑ(Aggregation) |
---|---|---|
๊ด๊ณ | ๊ฐํ ๊ด๊ณ (์ ์ฒด์ ๋ถ๋ถ์ด ๊ฐํ๊ฒ ๊ฒฐํฉ๋จ) | ์ฝํ ๊ด๊ณ (์ ์ฒด์ ๋ถ๋ถ์ด ๋ ๋ฆฝ์ ) |
์๋ช ์ฃผ๊ธฐ | ์ ์ฒด๊ฐ ์์ด์ง๋ฉด ๋ถ๋ถ๋ ์์ด์ง | ์ ์ฒด๊ฐ ์์ด์ ธ๋ ๋ถ๋ถ์ ์กด์ฌํ ์ ์์ |
๊ฐ์ฒด ์์ฑ ๋ฐฉ์ | ํฌํจํ๋ ๊ฐ์ฒด๊ฐ ์ง์ ๋ถ๋ถ ๊ฐ์ฒด๋ฅผ ์์ฑํจ | ํฌํจํ๋ ๊ฐ์ฒด๊ฐ ์ธ๋ถ์์ ๋ถ๋ถ ๊ฐ์ฒด๋ฅผ ๋ฐ์์ด |
์์กด์ฑ | ์ ์ฒด ๊ฐ์ฒด์ ๊ฐํ๊ฒ ์์กด (๋ ๋ฆฝ์ ์ผ๋ก ์กด์ฌ ๋ถ๊ฐ) | ์ฝํ ์์กด์ฑ (๋ถ๋ถ ๊ฐ์ฒด๋ ๋ ๋ฆฝ์ ์ผ๋ก ์กด์ฌ ๊ฐ๋ฅ) |
์์ | ์๋์ฐจ์ ์์ง | ํ๊ต์ ํ์ |
ํฉ์ฑ์ ๊ฐ์ฒด์งํฅ ์ค๊ณ์์ ์์์ ๋นํด ๋ ์ ์ฐํ๊ณ , ์ ์ง๋ณด์๊ฐ ์ฉ์ดํ ๋ฐฉ๋ฒ์ด๋ค. ํนํ ๊ฐ์ฒด ๊ฐ์ ๊ด๊ณ๋ฅผ ๋ ์์ ๋กญ๊ฒ ์ค๊ณํ๊ณ , ๋ณ๊ฒฝ์ด ์ฉ์ดํ๋ฉฐ, ๋ถํ์ํ ์์กด์ฑ์ ์ค์ผ ์ ์๋ค.
๋ณดํต ๋ณด๋๊น ์๋ฅผ ๋ค์ด WebController - WebBaseController์ฒ๋ผ ํด๋์ค ์ด๋ฆ๋ถํฐ is-a ๊ด๊ณ์ธ ์ ๋ค๋ง ์์์์ ์ฐ๋๋ผ
์์์ ์ง์ํ๊ณ ํฉ์ฑ์ ์งํฅํ๋ผ๋ ๋ง์, ์์์ ๋ฐ๋์ ์ด๋ ํ ํน์ ํ ๊ด๊ณ ์ผ ๋๋ง ์ฌ์ฉํ๋ผ๊ณ ์๊ฒฉํ๊ฒ ์ ํํ๋ผ๋ ๋ง์ด๋ฉฐ, ๊ทธ ๊ด๊ณ๊ฐ IS-A ๊ด๊ณ ์ธ ๊ฒ์ด๋ค.
ํญ๋ชฉ | ์์ (Inheritance) | ํฉ์ฑ (Composition) |
---|---|---|
์์กด์ฑ ํด๊ฒฐ | ๋ถ๋ชจ ํด๋์ค์ ์์ ํด๋์ค ์ฌ์ด์ ์์กด์ฑ์ ์ปดํ์ผ ํ์์ ํด๊ฒฐ๋จ | ๋ ๊ฐ์ฒด ์ฌ์ด์ ์์กด์ฑ์ ๋ฐํ์์ ํด๊ฒฐ๋จ |
๊ด๊ณ ์ ํ | "is-a" ๊ด๊ณ๋ฅผ ๋ํ๋ | "has-a" ๊ด๊ณ๋ฅผ ๋ํ๋ |
๊ฒฐํฉ๋ | ๋ถ๋ชจ ํด๋์ค์ ์์ ํด๋์ค ๊ฐ์ ๊ฒฐํฉ๋๊ฐ ๋์ | ํฌํจ๋ ๊ฐ์ฒด ๋๋ ์ธํฐํ์ด์ค์ ์์กดํ๋ฏ๋ก ๊ฒฐํฉ๋๊ฐ ๋ฎ์ |
์ฝ๋ ์ฌ์ฌ์ฉ | ์์ ํด๋์ค๊ฐ ๋ถ๋ชจ ํด๋์ค์ ๊ตฌํ์ ์ฌ์ฌ์ฉํจ | ํฌํจ๋ ๊ฐ์ฒด๋ ์ธํฐํ์ด์ค์ ์์ ์ ์์ํ์ฌ ์ฌ์ฌ์ฉํจ |
์ ์ฐ์ฑ | ํด๋์ค ๊ฐ์ ๊ฒฐํฉ์ด ๊ฐํด ์ ์ฐ์ฑ์ด ๋จ์ด์ง | ๊ฐ์ฒด ๊ฐ ๊ฒฐํฉ์ด ์ฝํ๊ณ ์ ์ฐ์ฑ์ด ๋์ |
์์ ์ ์ํฅ | ๋ถ๋ชจ ํด๋์ค์ ์์ ์ด ์์ ํด๋์ค์ ์ํฅ์ ์ค ์ ์์ | ๋ด๋ถ์ ์ผ๋ก ์์ ํ๊ธฐ ์ฉ์ดํ๋ฉฐ, ์ข ์์ฑ๋ ์ ์ |
ํฉ์ฑ
์ ๋ณดํต ๋ ์ ์ฐํ๊ณ ๋ชจ๋ํ๊ฐ ์ ๋์ด ์์ผ๋ฉฐ,์์
์ ์๋ชป ์ฌ์ฉํ๋ฉด ๊ฒฐํฉ๋๊ฐ ๋์์ ธ ์๊ธฐ์น ์์ ๋ฌธ์ ๊ฐ ๋ฐ์ํ ์ ์๋ค.
โ๏ธ OOP์ ๊ด์ ์์ ๋ดค์ ๋๋ ์์๋ณด๋ค๋ ์ปดํฌ์ง์ ์ด ๊ฐ์ฒด์ ์์จ์ฑ์ ์ธ์ ํ๋ฉด์๋ ์์ ์ ์ด๊ณ , ์บก์ํ๋ฅผ ๋ ์ข๊ฒ ์ด์ฉํ ์ ์๋ ๊ฒ ๊ฐ๋ค.
JetBrains์์ ๊ฐ๋ฐํ ํ๋ก๊ทธ๋๋ฐ ์ธ์ด๋ก, ์ฃผ๋ก ์๋ฐ๋ฅผ ๋์ฒดํ๊ฑฐ๋ ํจ๊ป ์ฌ์ฉํ ์ ์๋๋ก ์ค๊ณ๋์๋ค. ์ฝํ๋ฆฐ์ JVM(์๋ฐ ๊ฐ์ ๋จธ์ )์์ ์คํ๋๋ฉฐ, ์๋ฐ์ 100% ํธํ๋๊ธฐ ๋๋ฌธ์ ๊ธฐ์กด ์๋ฐ ํ๋ก์ ํธ์์ ๋ฌด๋ฆฌ ์์ด ์ฌ์ฉ์ด ๊ฐ๋ฅํ๋ค. ์ฝํ๋ฆฐ์ ์๋ฐ์์ ๋ถํธํ ์ ์ด๋ ํ๊ณ์ ์ ํด๊ฒฐํ๋ ๋ฐ ์ค์ ์ ๋์์ผ๋ฉฐ, ์๋ฐ๋ณด๋ค ๋ ๊ฐ๊ฒฐํ๊ณ ์์ ํ ์ฝ๋๋ฅผ ์์ฑํ ์ ์๊ฒ ํด์ค๋ค.
์ฝํ๋ฆฐ์ ๋ ์์ ์ฑ, ๊ฐ๊ฒฐํ ๋ฌธ๋ฒ, ํจ์ํ ํ๋ก๊ทธ๋๋ฐ ์ง์, ์ค๋งํธ ์บ์คํธ, ์์, ์ฝ๋ฃจํด ๋ฑ์ ๊ธฐ๋ฅ์ ์๋ฐ๋ณด๋ค ๋ ์์ ํ๊ณ ํจ์จ์ ์ธ ์ฝ๋๋ฅผ ์์ฑํ๋ ๋ฐ ํฐ ๋์์ ์ค๋ค.
๊ทธ๋ ๊ธฐ์ ์๋ฐ์์ ์์ ๋ฌธ์ ๋ฅผ ์ด๋ ์ ๋ ํด๊ฒฐํด์ค ๊ฑฐ๋ผ ์๊ฐํด์ ์ฐพ์๋ณด๊ฒ ๋จ
์ฝํ๋ฆฐ(Kotlin)์์๋ ์๋ฐ์ ๋ง์ฐฌ๊ฐ์ง๋ก ์์์ ์ง์ํ์ง๋ง, ์์์ ๋ฐ๋ฅธ ๋ฌธ์ ๋ฅผ ์ค์ด๊ธฐ ์ํด ๋ช ๊ฐ์ง ์ธ์ด์ ํน์ฑ์ ์ ๊ณตํ๋ค. ํนํ, ์์๊ณผ ๊ด๋ จ๋ ๋ฌธ์ ๋ฅผ ์๋ฐฉํ๊ฑฐ๋ ์ํํ๊ธฐ ์ํ ์ฝํ๋ฆฐ์ ์ค๊ณ ์ฒ ํ์ ์๋ฐ๋ณด๋ค ์๊ฒฉํ๊ณ ๋ ์์ ํ ๋ฐฉํฅ์ผ๋ก ๋์๊ฐ ์๋ค. ์ด๋ฐ ํน์ง๋ค์ด ์๋ฐ์์ ๋ฐ์ํ ์ ์๋ ์์ ๋ฌธ์ ๋ค์ ์ผ๋ถ ํด๊ฒฐํด์ค๋ค.
final
์ฝํ๋ฆฐ์์๋ ๋ชจ๋ ํด๋์ค๊ฐ ๊ธฐ๋ณธ์ ์ผ๋ก final
๋ก ์ ์ธ๋๋ค. ์ฆ, ๋ช
์์ ์ผ๋ก open
ํค์๋๋ฅผ ์ฌ์ฉํ์ง ์๋ ํ ํด๋์ค๋ ์์์ด ๋ถ๊ฐ๋ฅํ๋ค.
์๋ฐ ์์:
class Animal {
public void makeSound() {
System.out.println("Animal makes a sound");
}
}
class Dog extends Animal {
@Override
public void makeSound() {
System.out.println("Dog barks");
}
}
์ฝํ๋ฆฐ ์์:
open class Animal {
open fun makeSound() {
println("Animal makes a sound")
}
}
class Dog : Animal() {
override fun makeSound() {
println("Dog barks")
}
}
์ฝํ๋ฆฐ์์๋ ์์์ ์ฌ์ฉํ๊ณ ์ถ์ผ๋ฉด open
ํค์๋๋ฅผ ๋ช
์์ ์ผ๋ก ์ ์ธํด์ผ ํ๋ค. ์ด๋ ์์์ ๋จ์ฉ์ ์ค์ด๊ณ , ๋ถํ์ํ ์์์ ํตํ ๋ฌธ์ ๋ฅผ ๋ฐฉ์งํ๋ ๋ฐ ๋์์ ์ค๋ค.
sealed
ํด๋์ค์ฝํ๋ฆฐ์ sealed
ํด๋์ค๋ ์์์ ์ ํํ๋ ๋ ๋ค๋ฅธ ๋ฐฉ๋ฒ์ด๋ค. sealed
ํด๋์ค๋ ๊ฐ์ ํ์ผ ๋ด์์๋ง ํ์ ํด๋์ค๋ฅผ ์ ์ํ ์ ์๊ฒ ์ ํํ๋ฏ๋ก, ๊ณ์ธต ๊ตฌ์กฐ๋ฅผ ๋ช
ํํ ์ ์ํ๊ณ ์ธ๋ถ์์ ์์๋ก ํ์ฅํ์ง ๋ชปํ๊ฒ ๋ง๋๋ค.
์ฝํ๋ฆฐ ์์:
sealed class Animal {
class Dog : Animal()
class Cat : Animal()
}
์ด ๋ฐฉ์์ ํด๋์ค ๊ณ์ธต์ด ์ ํ์ ์ด๊ณ , ์๋๋ ์ฌ์ฉ์ ๋ฐ๋ผ๋ง ํ์ ํด๋์ค๋ฅผ ๋ง๋ค ์ ์๋๋ก ์ค๊ณ๋์ด ์์ ๋ฌธ์ ๋ฅผ ๋ฐฉ์งํ๋ ๋ฐ ๋์์ ์ค๋ค. ์ด๋ฅผ ํตํด ํด๋์ค ๊ณ์ธต์ ์์ธก ๊ฐ๋ฅ์ฑ์ ๋์ด๊ณ , ์๋ํ์ง ์์ ํ์ฅ์ ๋ง์ ์ ์๋ค.
data
ํด๋์คdata
ํด๋์ค๋ ๋ถ๋ณ ๊ฐ์ฒด๋ฅผ ์ฝ๊ฒ ๋ง๋ค ์ ์๋ ๊ธฐ๋ฅ์ ์ ๊ณตํ๋ค. ์ด๋ ์์๋ณด๋ค ์กฐํฉ(Composition)์ ์ฌ์ฉํ๋ ๋ฐฉํฅ์ ์ฅ๋ คํ๋ฉฐ, ๋ถํ์ํ ์์ ์์ด๋ ๊ฐ์ฒด์ ๊ธฐ๋ฅ์ ์ฝ๊ฒ ๊ด๋ฆฌํ ์ ์๊ฒ ํด์ค๋ค.
์ฝํ๋ฆฐ ์์:
data class Person(val name: String, val age: Int)
data
ํด๋์ค๋ฅผ ํตํด ๋ถ๋ณ ๊ฐ์ฒด๋ฅผ ๋ง๋ค๊ณ , ์์ ๋์ ์กฐํฉ์ ์ฌ์ฉํด ๊ฐ์ฒด ๊ฐ์ ๊ด๊ณ๋ฅผ ์ค๊ณํ๋๋ก ์ ๋ํ ์ ์๋ค. ์ด๋ ์์์ผ๋ก ์ธํ ๋ฆฌ์ค์ฝํ ์นํ ์์น(LSP) ์๋ฐ ๋ฌธ์ ๋ฅผ ๋ฐฉ์งํ ์ ์๋ ์ข์ ๋์์ด๋ค.
default
๋ฉ์๋ ๋ฌธ์ ํด๊ฒฐdefault
๋ฉ์๋์ ์ ์ฌํ ๊ธฐ๋ฅ์ ์ ๊ณตํ๋ค. ํ์ง๋ง ์ฝํ๋ฆฐ์์๋ ์ธํฐํ์ด์ค์ ๋ฉ์๋ ์ถฉ๋ ๋ฌธ์ ๊ฐ ๋ ๋ช
ํํ๊ฒ ์ฒ๋ฆฌ๋๋ฉฐ, ๋ฉ์๋ ๊ตฌํ์ด ๋ช
์์ ์ด๋ฏ๋ก ์์ ๊ตฌ์กฐ์์ ๋ฐ์ํ ์ ์๋ ํผ๋์ ์ค์ธ๋ค.by
ํค์๋๋ก ์์(Delegation)์ฝํ๋ฆฐ์์๋ ์์์ ์ฌ์ฉํ์ง ์๊ณ ์์(Delegation)์ ํตํด ์ฝ๋ ์ฌ์ฌ์ฉ์ฑ์ ๋์ด๋ ๊ธฐ๋ฅ์ ์ ๊ณตํ๋ค. ์ด๋ฅผ ํตํด ์์ ๋์ ๊ฐ์ฒด์ ๊ธฐ๋ฅ์ ๋ค๋ฅธ ๊ฐ์ฒด์ ์์ํ๋ ๋ฐฉ์์ผ๋ก ๊ตฌ์กฐ๋ฅผ ์ค๊ณํ ์ ์๋ค. ์ด ๋ฐฉ์์ ์์์ ๋ฌธ์ ์ ์ธ ๋ฆฌ์ค์ฝํ ์นํ ์์น ์๋ฐ์ ํผํ๋ ๋ฐ ๋์์ ์ค๋ค.
์ฝํ๋ฆฐ ์์:
interface Sound {
fun makeSound()
}
class Dog : Sound {
override fun makeSound() {
println("Dog barks")
}
}
class Cat : Sound {
override fun makeSound() {
println("Cat meows")
}
}
class Animal(sound: Sound) : Sound by sound
์ด๋์ ๋ค๋ค.. ์ฝํ๋ฆฐ ์ฝํ๋ฆฐ ํ๋ ๊ฑด๊ฐ ์ถ์...
๐ ์ฐธ๊ณ ๊ธ
- ์์์ ์์ ํ๊ณ ํฉ์ฑ์ ์ด์ฉํ์
- ์์ ๋์ ์กฐํฉ
- ์ดํํฐ๋ธ ์๋ฐ