์ผ๋ฐ์ ์ธ ๊ตฌ์ฒด ํด๋์ค๋ฅผ ํจํค์ง ๊ฒฝ๊ณ๋ฅผ ๋์ด, ์ฆ ๋ค๋ฅธ ํจํค์ง์ ๊ตฌ์ฒด ํด๋์ค๋ฅผ ์์ํ๋ ์ผ์ ์ํํ๋ค. ์๊ธฐํ์๋ฉด, ์ด ์ฑ ์์์ โ์์โ์ ํด๋์ค๊ฐ ๋ค๋ฅธ ํด๋์ค๋ฅผ ํ์ฅํ๋ ๊ตฌํ ์์์ ๋งํ๋ค. ์ด๋ฒ ์์ดํ ์์ ๋ ผํ๋ ๋ฌธ์ ๋ ํด๋์ค๊ฐ ์ธํฐํ์ด์ค๋ฅผ ๊ตฌํํ๊ฑฐ๋ ์ธํฐํ์ด์ค๊ฐ ๋ค๋ฅธ ์ธํฐํ์ด์ค๋ฅผ ํ์ฅํ๋ ์ธํฐ ํ์ด์ค ์์๊ณผ๋ ๋ฌด๊ดํ๋ค.
- ํ ํด๋์ค๊ฐ ๋ค๋ฅธ ํด๋์ค์ ์์ฑ๊ณผ ๋ฉ์๋๋ฅผ ํ์ฅ ํน์ ์ฌ์ ์ํ ์ ์๋๋ก ํด์ฃผ๋ ๋งค์ปค๋์ฆ
{% hint style="danger" %} ์์์ ์ฝ๋๋ฅผ ์ฌ์ฌ์ฉํ๋ ๊ฐ๋ ฅํ ์๋จ์ด์ง๋ง, ํญ์ ์ต์ ์ ์๋๋ค {% endhint %}
- ๊ฐํ ๊ฒฐํฉ : ๋ถ๋ชจ ํด๋์ค์ ๋ด๋ถ ๋ณ๊ฒฝ์ด ์์ ํด๋์ค์ ์ํฅ์ ์ค ์ ์์ด ์ ์ฐ์ฑ์ด ์ ํ๋๋ค.
- ์บก์ํ ์๋ฐ : ์์ ํด๋์ค๊ฐ ๋ถ๋ชจ ํด๋์ค์ ๊ตฌํ ์ธ๋ถ ์ฌํญ์ ์์กดํ๊ฒ๋๋ฉด, ์บก์ํ๊ฐ ์ฝํ๋๋ค.
- ์ฌ์ฌ์ฉ์ฑ ์ ํ : ํน์ ๊ตฌํ์ ๊ฐํ๊ฒ ๊ฒฐํฉ๋ ์์ ๊ตฌ์กฐ๋ ์๋ก์ด ์ํฉ์ ์ฌ์ฌ์ฉํ๊ธฐ ์ด๋ ต๋ค.
๋ค๋ฅด๊ฒ ๋งํ๋ฉด, ์์ ํด๋์ค๊ฐ ์ด๋ป๊ฒ ๊ตฌํ๋๋๋์ ๋ฐ๋ผ ํ์ ํด๋์ค์ ๋์์ ์ด์์ด ์๊ธธ ์ ์๋ค.
์๋ชป๋ ์์์ ์
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๋ฉ์๋๋ฅผ ํธ์ถํ๊ธฐ ๋๋ฌธ์ด๋ค.
addAll์ ํธ์ถํ๋ฉด ๋ด๋ถ์์add๋ฅผ ํธ์ถํ๋๋ฐadd๊ฐ ์์ ํด๋์ค์ add๋ฅผ ํธ์ถํ ์ค ์์์ง๋งInstrumentedHashSet์add๋ฅผ ํธ์ถํ๋ค.
์์์์ ๋ฌธ์ ๋ ๋ฉ์๋ ์ฌ์ ์ ์ ๋น์ฅ์ ํด๊ฒฐํ ์ ์์ผ๋, HashSet์ addAll์ด add ๋ฉ์๋๋ฅผ ์ด์ฉํด ๊ตฌํํ์์ ๊ฐ์ ํ ํด๋ฒ์ด๋ผ๋ ํ๊ณ๋ฅผ ์ง๋๋ค. ์ด์ฒ๋ผ ์์ ์ ๋ค๋ฅธ ๋ถ๋ถ์ ์ฌ์ฉํ๋ โ์๊ธฐ์ฌ์ฉ(self-use)1โ ์ฌ๋ถ๋ ํด๋น ํด๋์ค์ ๋ด๋ถ ๊ตฌํ ๋ฐฉ์ ์ ํด๋นํ๋ฉฐ, ์๋ฐ ํ๋ซํผ ์ ๋ฐ์ ์ธ ์ ์ฑ
์ธ์ง, ๊ทธ๋์ ๋ค์ ๋ฆด๋ฆฌ์ค์์๋ ์ ์ง๋ ์ง๋ ์ ์ ์๋ค. ๋ฐ๋ผ์ ์ด๋ฐ ๊ฐ์ ์ ๊ธฐ๋ InstrumentedHashSet2๋ ๊นจ์ง๊ธฐ ์ฝ๋ค.
addAll ๋ฉ์๋๋ฅผ ๋ค๋ฅธ ์์ผ๋ก ์ฌ์ ์ํ ์๋ ์๋ค. ์ฃผ์ด์ง ์ปฌ๋ ์
์ ์ํํ๋ฉฐ ์์ ํ๋๋น add ๋ฉ์๋๋ฅผ ํ๋๋ง ํธ์ถํ๋ ๊ฒ์ด๋ค. ์กฐ๊ธ ๋์ ๋ฐฉ๋ฒ์ด์ง๋ง ์์ ํด๋์ค์ ๋ฉ์๋ ๋์์ ๋ค์ ๊ตฌํํ๋ ๊ฒ์ ์ด๋ ต๊ณ , ๋น์ฉ์ด ๋ ๋ค. ๋ํ ํ์ ํด๋์ค์์ ์ ๊ทผํ ์ ์๋ private ํ๋๋ฅผ ์จ์ผ ํ๋ค๋ฉด ์ด ๋ฐฉ์์ผ๋ก๋ ๊ตฌํ ์์ฒด๊ฐ ๋ถ๊ฐ๋ฅํ๋ค.
- ์์ ํด๋์ค์ ๊ตฌํ์ ์์กด:
HashSet์ ๋ด๋ถ ๊ตฌํ์ดaddAll()์์add()๋ฅผ ํธ์ถํ๋ค๋ ์ฌ์ค์ ์์กดํ๊ณ ์๋ค. - ๋ฉ์๋ ์ค๋ฒ๋ผ์ด๋ฉ์ ์ํ์ฑ: ์์ ํด๋์ค์ ๋ฉ์๋๋ฅผ ์ฌ์ ์ํ๋ฉด, ์์ ํด๋์ค์ ๋ด๋ถ ๊ตฌํ์ด ๋ณ๊ฒฝ๋ ๋ ํ์ ํด๋์ค์ ๋์์ด ์๊ธฐ์น ์๊ฒ ๋ณํ ์ ์๋ค.
{% hint style="info" %} ๊ทธ๋ ๋ค๋ฉด ์์์์ ๋ฌธ์ ๋ ๋ค ๋ฉ์๋ ์ฌ์ ์ ์๋๊น ์๋ก์ด ๋ฉ์๋๋ฅผ ์ถ๊ฐํ๋ค๋ฉด? {% endhint %}
์ด ๋ฐฉ์์ด ํจ์ฌ ์์ ํ ๊ฒ์ ๋ง์ง๋ง, ์ํ์ด ์ ํ ์๋ ๊ฒ์ ์๋๋ค. ๋ค์ ๋ฆด๋ฆฌ์ค์์ ์์ ํด๋์ค์ ์ ๋ฉ์๋๊ฐ ์ถ๊ฐ๋๋๋ฐ, ํํ ํ์ ํด๋์ค์ ์ถ๊ฐํ ๋ฉ์๋์ ์๊ทธ๋์ฒ๊ฐ ๊ฐ๊ณ ๋ฐํ ํ์ ์ ๋ค๋ฅด ๋ค๋ฉด ์ฌ๋ฌ๋ถ์ ํด๋์ค๋ ์ปดํ์ผ์กฐ์ฐจ ๋์ง ์์ ์ ์๋ค.
{% hint style="warning" %} ํ๋์ ํด๋์ค๊ฐ ๋ค๋ฅธ ํด๋์ค์ ์ธ์คํด์ค๋ฅผ ํฌํจํ์ฌ, ๊ทธ ์ธ์คํด์ค์ ๋ฉ์๋๋ฅผ ํ์ฉํ๋ ๋ฐฉ์ {% endhint %}
๊ธฐ์กด ํด๋์ค๋ฅผ ํ์ฅํ๋ ๋์ , ์๋ก์ด ํด๋์ค๋ฅผ ๋ง๋ค๊ณ 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)์ด๋ผ๊ณ ๋ถ๋ฅธ๋ค.
{% hint style="success" %}
์์์ ๋ฐ๋์ ํ์ ํด๋์ค๊ฐ ์์ ํด๋์ค์ '์ง์ง' ํ์ ํ์
์ธ ์ํฉ์์๋ง ์ฐ์ฌ์ผ ํ๋ค. ๋ค๋ฅด๊ฒ ๋งํ๋ฉด, ํด๋์ค B๊ฐ ํด๋์ค A์ is-a ๊ด๊ณ์ผ ๋๋ง ํด๋์ค A๋ฅผ ์์ํด์ผ ํ๋ค.
{% endhint %}
์ปดํฌ์ง์ ์ ์จ์ผ ํ ์ํฉ์์ ์์์ ์ฌ์ฉํ๋ ๊ฑด ๋ด๋ถ ๊ตฌํ์ ๋ถํ์ํ๊ฒ ๋ ธ์ถํ๋ ๊ผด์ด๋ค. ๊ทธ ๊ฒฐ๊ณผ API๊ฐ ๋ด๋ถ ๊ตฌํ์ ๋ฌถ์ด๊ณ ๊ทธ ํด๋์ค์ ์ฑ๋ฅ๋ ์์ํ ์ ํ๋๋ค. ๋ ์ฌ๊ฐํ ๋ฌธ์ ๋ ํด๋ผ์ด์ธํธ๊ฐ ๋ ธ์ถ๋ ๋ด๋ถ์ ์ง์ ์ ๊ทผํ ์ ์๋ค๋ ์ ์ด๋ค.
{% hint style="info" %} ๋ํผ ํด๋์ค๋ ๋จ์ ์ด ๊ฑฐ์ ์๋ค. ํ ๊ฐ์ง, ๋ํผ ํด๋์ค๊ฐ ์ฝ๋ฐฑ(callback) ํ๋ ์์ํฌ์๋ ์ด์ธ๋ฆฌ์ง ์๋๋ค๋ ์ ๋ง ์ฃผ์ํ๋ฉด ๋๋ค. {% endhint %}
์ฝ๋ฐฑ ํ๋ ์์ํฌ์์ ๋ ์๊ธฐ ์์ ์ ์ฐธ์กฐ๋ฅผ ๋ค๋ฅธ ๊ฐ์ฒด์ ๋๊ฒจ์ ๋ค์ ํธ์ถ(์ฝ๋ฐฑ) ๋ ์ฌ์ฉํ๋๋ก ํ๋ค. ๋ด๋ถ ๊ฐ์ฒด๋ ์์ ์ ๊ฐ์ธ๊ณ ์๋ ๋ํผ์ ์กด์ฌ๋ฅผ ๋ชจ๋ฅด๋ ๋์ ์์ (this)์ ์ฐธ์กฐ๋ฅผ ๋๊ธฐ๊ณ , ์ฝ๋ฐฑ ๋๋ ๋ํผ๊ฐ ์๋ ๋ด๋ถ ๊ฐ์ฒด๋ฅผ ํธ์ถํ๊ฒ ๋๋ค. ์ด๋ฅผ SELF ๋ฌธ์ ๋ผ๊ณ ํ๋ค.
์ ๋ฌ ๋ฉ์๋๊ฐ ์ฑ๋ฅ์ ์ฃผ๋ ์ํฅ์ด๋ ๋ํผ ๊ฐ์ฒด๊ฐ ๋ฉ๋ชจ๋ฆฌ ์ฌ์ฉ๋์ ์ฃผ๋ ์ํฅ์ ๊ฑฑ์ ํ๋ ์ฌ๋๋ ์์ง๋ง, ์ค์ ์์๋ ๋ ๋ค ๋ณ๋ค๋ฅธ ์ํฅ์ด ์๋ค๊ณ ๋ฐํ์ก๋ค. ์ ๋ฌ ๋ฉ์๋๋ค์ ์์ฑํ๋ ๊ฒ ์ฌ์ฌ์ฉํ ์ ์๋ ์ ๋ฌ ํด๋์ค๋ฅผ ์ธํฐ ํ์ด์ค๋น ํ๋์ฉ๋ง ๋ง๋ค์ด๋ ๋ฉด ์ํ๋ ๊ธฐ๋ฅ์ ๋ง์์ฐ๋ ์ ๋ฌ ํด๋์ค๋ค์ ์์ฃผ ์์ฝ๊ฒ ๊ตฌํํ ์ ์๋ค.
์์ : ์ ์๊ธฐ๊ธฐ(ElectronicDevice)์ ์ค๋งํธํฐ(Smartphone)
class ElectronicDevice {
public void powerOn() {
System.out.println("์ ์๊ธฐ๊ธฐ๊ฐ ์ผ์ก์ต๋๋ค.");
}
public void powerOff() {
System.out.println("์ ์๊ธฐ๊ธฐ๊ฐ ๊บผ์ก์ต๋๋ค.");
}
}- ์ค๋ช
:
ElectronicDeviceํด๋์ค๋ ์ ์๊ธฐ๊ธฐ์ ์ผ๋ฐ์ ์ธ ๋์์ธpowerOn()๊ณผpowerOff()๋ฉ์๋๋ฅผ ๊ฐ์ง๊ณ ์๋ค.
class Smartphone extends ElectronicDevice {
public void makeCall(String number) {
System.out.println(number + "๋ก ์ ํ๋ฅผ ๊ฒ๋๋ค.");
}
public void browseInternet() {
System.out.println("์ธํฐ๋ท์ ๊ฒ์ํฉ๋๋ค.");
}
}- ์ค๋ช
:
Smartphoneํด๋์ค๋ElectronicDevice๋ฅผ ์์๋ฐ์ ์ ์๊ธฐ๊ธฐ์ ๊ธฐ๋ฅ์ ํ์ฅํ๋ค. - ๊ด๊ณ:
Smartphone์ElectronicDevice์ด๋ค๋ผ๋ Is-a ๊ด๊ณ๋ฅผ ํ์ฑํ๋ค.
public class Main {
public static void main(String[] args) {
Smartphone myPhone = new Smartphone();
myPhone.powerOn(); // ์ ์๊ธฐ๊ธฐ๊ฐ ์ผ์ก์ต๋๋ค.
myPhone.makeCall("010-1234-5678"); // 010-1234-5678๋ก ์ ํ๋ฅผ ๊ฒ๋๋ค.
myPhone.browseInternet(); // ์ธํฐ๋ท์ ๊ฒ์ํฉ๋๋ค.
myPhone.powerOff(); // ์ ์๊ธฐ๊ธฐ๊ฐ ๊บผ์ก์ต๋๋ค.
}
}- ๊ฒฐ๊ณผ:
Smartphone๊ฐ์ฒด๋ElectronicDevice์ ๋ฉ์๋์ธpowerOn()๊ณผpowerOff()๋ฅผ ๊ทธ๋๋ก ์ฌ์ฉํ ์ ์๋ค.
์์ : Battery ํด๋์ค์ Laptop ํด๋์ค
class Battery {
private int capacity; // ๋ฐฐํฐ๋ฆฌ ์ฉ๋ (๋จ์: mAh)
public Battery(int capacity) {
this.capacity = capacity;
}
public void supplyPower() {
System.out.println("๋ฐฐํฐ๋ฆฌ์์ ์ ์์ ๊ณต๊ธํฉ๋๋ค. ์ฉ๋: " + capacity + "mAh");
}
public void charge() {
System.out.println("๋ฐฐํฐ๋ฆฌ๋ฅผ ์ถฉ์ ํฉ๋๋ค.");
}
}- ์ค๋ช
:
Batteryํด๋์ค๋ ๋ฐฐํฐ๋ฆฌ์ ๋์์ ์ ์ํ๋ค.
class Laptop {
private Battery battery;
public Laptop(int batteryCapacity) {
this.battery = new Battery(batteryCapacity);
}
public void powerOn() {
battery.supplyPower(); // ์์: Laptop์ Battery์ ๊ธฐ๋ฅ์ ์ฌ์ฉํฉ๋๋ค.
System.out.println("๋
ธํธ๋ถ์ด ์ผ์ก์ต๋๋ค.");
}
public void powerOff() {
System.out.println("๋
ธํธ๋ถ์ด ๊บผ์ก์ต๋๋ค.");
}
public void chargeLaptop() {
battery.charge(); // Battery์ ๋ฉ์๋๋ฅผ ํธ์ถ
}
}- ์ค๋ช
:
Laptopํด๋์ค๋Battery๊ฐ์ฒด๋ฅผ ๊ตฌ์ฑ์์๋ก ํฌํจํ๊ณ ์๋ค. - ๊ด๊ณ:
Laptop์Battery๋ฅผ ๊ฐ์ง๋ค๋ผ๋ Has-a ๊ด๊ณ๋ฅผ ํ์ฑํ๋ค.
public class Main {
public static void main(String[] args) {
Laptop myLaptop = new Laptop(5000);
myLaptop.powerOn(); // ๋ฐฐํฐ๋ฆฌ์์ ์ ์์ ๊ณต๊ธํฉ๋๋ค. ์ฉ๋: 5000mAh
// ๋
ธํธ๋ถ์ด ์ผ์ก์ต๋๋ค.
myLaptop.chargeLaptop(); // ๋ฐฐํฐ๋ฆฌ๋ฅผ ์ถฉ์ ํฉ๋๋ค.
myLaptop.powerOff(); // ๋
ธํธ๋ถ์ด ๊บผ์ก์ต๋๋ค.
}
}- ๊ฒฐ๊ณผ:
Laptop๊ฐ์ฒด๋Battery๊ฐ์ฒด์ ๊ธฐ๋ฅ์ ์ฌ์ฉํ์ฌ ๋์์ ์ํํ3๋ค.
- ์์(Inheritance): Is-a ๊ด๊ณ๋ฅผ ๋ํ๋ธ๋ค
- ์ปดํฌ์ง์
(Composition):
- Has-a ๊ด๊ณ๋ฅผ ๋ํ๋ ๋๋ค.
- ํ ํด๋์ค๊ฐ ๋ค๋ฅธ ํด๋์ค์ ๊ฐ์ฒด๋ฅผ ๊ตฌ์ฑ์์๋ก ํฌํจํ๊ณ , ๊ทธ ๊ธฐ๋ฅ์ ์ฌ์ฉํฉ๋๋ค.
- ์์:
Laptop์Battery๋ฅผ ๊ฐ์ง๋ค.
- ์์:
- ๋ถ๋ชจ ํด๋์ค์ ๋ชจ๋ public ๋ฐ protected ๋ฉค๋ฒ๋ฅผ ์๋์ผ๋ก ์์๋ฐ์ต๋๋ค.
- ์ฝ๋ ์ฌ์ฌ์ฉ์ด ์ฝ์ง๋ง, ๋ถ๋ชจ ํด๋์ค์ ๊ฐํ ๊ฒฐํฉ์ด ๋ฐ์ํฉ๋๋ค.
- ์ปดํฌ์ง์
:
- ํ์ํ ๊ธฐ๋ฅ๋ง ์ ํ์ ์ผ๋ก ์ฌ์ฉ ๊ฐ๋ฅํฉ๋๋ค.
- ๊ตฌ์ฑ์์ ํด๋์ค์ ์ธํฐํ์ด์ค๋ฅผ ํตํด์๋ง ์ ๊ทผํ๋ฏ๋ก ๊ฒฐํฉ๋๊ฐ ๋ฎ์ต๋๋ค.
- ์์:
- ๋ถ๋ชจ ํด๋์ค์ ๋ณ๊ฒฝ์ด ์์ ํด๋์ค์ ์ํฅ์ ๋ฏธ์นฉ๋๋ค.
- ๋ถ๋ชจ ํด๋์ค์ ๋ด๋ถ ๊ตฌํ์ ์์ ํด๋์ค๊ฐ ์์กดํ๊ฒ ๋๋ฉด, ์๊ธฐ์น ์์ ๋ฒ๊ทธ๊ฐ ๋ฐ์ํ ์ ์์ต๋๋ค.
- ์ปดํฌ์ง์
:
- ๊ตฌ์ฑ์์์ ๋ณ๊ฒฝ์ด ์๋์ ์ผ๋ก ๋ ์ํฅ์ ๋ฏธ์นฉ๋๋ค.
- ํด๋์ค ๊ฐ์ ๊ฒฐํฉ๋๊ฐ ๋ฎ์ ์ ์ง๋ณด์๊ฐ ์ฉ์ดํฉ๋๋ค.
- ์์:
-
์์ ํด๋์ค๋ ๋ถ๋ชจ ํด๋์ค ํ์ ์ผ๋ก ์ทจ๊ธ๋ ์ ์์ด ๋คํ์ฑ์ ํ์ฉํ ์ ์์ต๋๋ค.
-
์์:
ElectronicDevice device = new Smartphone(); device.powerOn(); // ์ ์๊ธฐ๊ธฐ๊ฐ ์ผ์ก์ต๋๋ค.
-
- ์ปดํฌ์ง์
:
- ๋คํ์ฑ๋ณด๋ค๋ ๊ธฐ๋ฅ ํ์ฅ์ด๋ ์กฐํฉ์ ์ค์ ์ ๋ก๋๋ค.
- ํด๋์ค ๊ฐ์ Is-a ๊ด๊ณ๊ฐ ๋ช ํํ ๋.
- ๋ถ๋ชจ ํด๋์ค์ ๋์์ ๊ทธ๋๋ก ๋ฌผ๋ ค๋ฐ์ ์ฌ์ฉํ๊ฑฐ๋, ๋์์ ํ์ฅํด์ผ ํ ๋.
- ๋คํ์ฑ์ ์ ๊ทน์ ์ผ๋ก ํ์ฉํ์ฌ ์ฝ๋์ ์ ์ฐ์ฑ์ ๋์ด๊ณ ์ ํ ๋.
- ํด๋์ค ๊ฐ์ Has-a ๊ด๊ณ๊ฐ ์์ ๋.
- ๊ธฐ๋ฅ์ ์ฌ์ฌ์ฉํ๊ณ ์ถ์ง๋ง, ๋ถ๋ชจ ํด๋์ค์ ๊ฐํ ๊ฒฐํฉ์ ํผํ๊ณ ์ ํ ๋.
- ๊ธฐ์กด ํด๋์ค์ ์ผ๋ถ ๊ธฐ๋ฅ๋ง ํ์ฉํ๊ฑฐ๋, ๋ด๋ถ ๊ตฌํ์ ์์กดํ์ง ์๊ณ ์์ ์ ์ธ ์ฝ๋๋ฅผ ์์ฑํ๊ณ ์ ํ ๋.
- ์ฝ๋ ์ฌ์ฌ์ฉ์ด ์ฝ์ต๋๋ค.
- ๋คํ์ฑ์ ํ์ฉํ์ฌ ์ ์ฐํ ์ฝ๋๋ฅผ ์์ฑํ ์ ์์ต๋๋ค.
- ๋ถ๋ชจ ํด๋์ค์ ๊ธฐ๋ฅ์ ๊ทธ๋๋ก ์ฌ์ฉํ๊ฑฐ๋, ํ์ํ ๊ฒฝ์ฐ ์ฌ์ ์ํ์ฌ ํ์ฅํ ์ ์์ต๋๋ค.
- ๋ถ๋ชจ ํด๋์ค์ ๊ฐํ ๊ฒฐํฉ์ด ๋ฐ์ํ์ฌ, ๋ถ๋ชจ ํด๋์ค์ ๋ณ๊ฒฝ์ด ์์ ํด๋์ค์ ์ํฅ์ ๋ฏธ์นฉ๋๋ค.
- ์๋ชป๋ ์์ ๊ตฌ์กฐ๋ ์ ์ง๋ณด์์ฑ์ ๋จ์ด๋จ๋ฆฌ๊ณ , ์ฝ๋์ ์์ ์ฑ์ ํด์น ์ ์์ต๋๋ค.
- ์์ ํด๋์ค๊ฐ ๋ถ๋ชจ ํด๋์ค์ ๋ถํ์ํ ๊ธฐ๋ฅ๊น์ง ์์๋ฐ์ ์ ์์ต๋๋ค.
- ํด๋์ค ๊ฐ์ ๊ฒฐํฉ๋๊ฐ ๋ฎ์ ์ ์ง๋ณด์๊ฐ ์ฉ์ดํฉ๋๋ค.
- ํ์ํ ๊ธฐ๋ฅ๋ง ์ ํ์ ์ผ๋ก ์ฌ์ฉ ๊ฐ๋ฅํ๋ฉฐ, ์ฝ๋์ ์ฌ์ฌ์ฉ์ฑ์ด ๋์ต๋๋ค.
- ๋ด๋ถ ๊ตฌํ์ ์์กดํ์ง ์์ผ๋ฏ๋ก, ๊ตฌ์ฑ์์ ํด๋์ค์ ๋ณ๊ฒฝ์๋ ์์ ์ ์ ๋๋ค.
- ์์์ ๋นํด ๊ตฌํํด์ผ ํ ์ฝ๋๊ฐ ๋ง์์ง ์ ์์ต๋๋ค.
- ๋คํ์ฑ์ ํ์ฉํ๊ธฐ ์ด๋ ค์ธ ์ ์์ต๋๋ค.
- ๋ฉ์๋ ์์์ด ํ์ํ์ฌ ์ฝ๋๊ฐ ์ฅํฉํด์ง ์ ์์ต๋๋ค.
์์์ ์์: Shape ํด๋์ค์ Circle ํด๋์ค
// ๋ถ๋ชจ ํด๋์ค: ๋ํ
abstract class Shape {
public abstract void draw();
}
// ์์ ํด๋์ค: ์
class Circle extends Shape {
@Override
public void draw() {
System.out.println("์์ ๊ทธ๋ฆฝ๋๋ค.");
}
}- ์ค๋ช
:
Circle์Shape์ ์ผ์ข ์ด๋ฏ๋ก ์์์ ์ฌ์ฉํฉ๋๋ค.
์ปดํฌ์ง์
์ ์์: Canvas ํด๋์ค์ Pen ํด๋์ค
// ๋
๋ฆฝ๋ ๊ธฐ๋ฅ์ ๊ฐ์ง ํด๋์ค: ํ
class Pen {
public void setColor(String color) {
System.out.println(color + " ์์ผ๋ก ์ค์ ํฉ๋๋ค.");
}
public void drawLine() {
System.out.println("์ ์ ๊ทธ๋ฆฝ๋๋ค.");
}
}
// ์ปดํฌ์ง์
์ ์ฌ์ฉํ๋ ํด๋์ค: ์บ๋ฒ์ค
class Canvas {
private Pen pen;
public Canvas() {
this.pen = new Pen();
}
public void drawShape(Shape shape) {
pen.setColor("๊ฒ์์");
shape.draw();
pen.drawLine();
}
}- ์ค๋ช
:
Canvasํด๋์ค๋Pen๊ฐ์ฒด๋ฅผ ์ฌ์ฉํ์ฌ ๋ํ์ ๊ทธ๋ฆฝ๋๋ค. - ๊ด๊ณ:
Canvas๋Pen์ ๊ฐ์ง๊ณ ์์ผ๋ฉฐ,Shape๊ฐ์ฒด๋ฅผ ์ฌ์ฉํ์ฌ ๊ทธ๋ฆผ์ ๊ทธ๋ฆฝ๋๋ค.
- ์์์ is-a ๊ด๊ณ์ผ ๋๋ง ์ฌ์ฉํด์ผ ํ๋ค. ํด๋์ค ๊ฐ์ ๊ณ์ธต ๊ตฌ์กฐ๋ฅผ ํ์ฑํ ๋ ๋ง์ด๋ค. ์ฆ, ํ์ ํด๋์ค๊ฐ ์์ ํด๋์ค์ ์ง์ง ํ์ ํ์ ์ธ ๊ฒฝ์ฐ์๋ง ์์์ ์ฌ์ฉํด์ผ ํ๋ค. ๋ด๋ถ ๊ตฌํ์ ์์กดํ๊ฑฐ๋ ๊ฐํ ๊ฒฐํฉ์ด ๋ฐ์ํ ์ ์์ผ๋ฏ๋ก ์ฃผ์ํด์ผ ํ๋ค.
- ์ปดํฌ์ง์ ์ Has-a ๊ด๊ณ๋ฅผ ๋ํ๋ด๋ฉฐ, ํด๋์ค์ ๊ธฐ๋ฅ์ ์ ์ฐํ๊ฒ ํ์ฅํ๊ณ ์ฌ์ฌ์ฉํ ์ ์๋ค. ์ปดํฌ์ง์ ๊ณผ ์์์ ์ฌ์ฉํ๋ฉด ์์์ ๋จ์ ์ ํผํ๋ฉด์ ์ ์ฐํ๊ณ ์์ ํ๊ฒ ๊ธฐ๋ฅ์ ํ์ฅํ ์ ์๋ค. ํ์ง๋ง๊ฒฐํฉ๋๊ฐ ๋ฎ์ ์ ์ง๋ณด์๊ฐ ์ฉ์ดํ์ง๋ง, ๋คํ์ฑ ํ์ฉ์ด ์ ํ์ ์ผ ์ ์๋ค.
- ๋ํผ ํด๋์ค๋ฅผ ์ฌ์ฉํ๋ฉด ๊ธฐ์กด ํด๋์ค์ ๋ด๋ถ ๊ตฌํ์ ์์กดํ์ง ์๊ณ ๋ ๊ธฐ๋ฅ์ ์ถ๊ฐํ๊ฑฐ๋ ๋ณ๊ฒฝํ ์ ์๋ค.
- ํนํ, ์์ ํด๋์ค์ ์๋ก์ด ๋ฉ์๋๊ฐ ์ถ๊ฐ๋๋๋ผ๋ ํ์ ํด๋์ค์ ๋์์ ์ํฅ์ ์ฃผ์ง ์๋๋ค.
์ฐธ๊ณ ๊ธ
Footnotes
-
์๊ธฐ์ฌ์ฉ(self-use)์ด๋ ๋ฌด์์ธ๊ฐ์?
์๊ธฐ์ฌ์ฉ(self-use)์ ๊ฐ์ฒด ์งํฅ ํ๋ก๊ทธ๋๋ฐ์์ ํด๋์ค ๋ด์ ๋ฉ์๋๊ฐ ๊ฐ์ ํด๋์ค์ ๋ค๋ฅธ ๋ฉ์๋๋ฅผ ํธ์ถํ์ฌ ๊ธฐ๋ฅ์ ๊ตฌํํ๋ ๊ฒ์ ์๋ฏธํฉ๋๋ค. ์ฆ, ํด๋์ค์ ๋ฉ์๋๋ค์ด ์๋ก๋ฅผ ํธ์ถํ์ฌ ๋์์ ์ํํ๋ ๊ฒ์ ๋งํฉ๋๋ค.
์์๋ก ์ดํดํ๊ธฐ
์๋ฅผ ๋ค์ด,
HashSetํด๋์ค์์addAll()๋ฉ์๋๊ฐadd()๋ฉ์๋๋ฅผ ์ฌ์ฉํ์ฌ ๊ตฌํ๋์ด ์๋ค๋ฉด, ์ด๋addAll()๋ฉ์๋๊ฐadd()๋ฉ์๋๋ฅผ ์๊ธฐ์ฌ์ฉํ๊ณ ์๋ค๊ณ ๋งํ ์ ์์ต๋๋ค.java์ฝ๋ ๋ณต์ฌpublic class HashSet<E> implements Set<E> { // ... public boolean addAll(Collection<? extends E> c) { boolean modified = false; for (E e : c) { if (add(e)) { // ์ฌ๊ธฐ์ add() ๋ฉ์๋๋ฅผ ํธ์ถํฉ๋๋ค. modified = true; } } return modified; } public boolean add(E e) { // ์์๋ฅผ ์ถ๊ฐํ๋ ๋ก์ง } // ... }์ ์ฝ๋์์ ๋ณด๋ฏ์ด,
addAll()๋ฉ์๋๋ ๋ด๋ถ์ ์ผ๋กadd()๋ฉ์๋๋ฅผ ํธ์ถํ์ฌ ์ปฌ๋ ์ ์ ๊ฐ ์์๋ฅผ ์ถ๊ฐํฉ๋๋ค. ์ด๋addAll()์ดadd()๋ฅผ ์๊ธฐ์ฌ์ฉํ๊ณ ์๋ ๊ฒ์ ๋๋ค.์ ์๊ธฐ์ฌ์ฉ์ด ๋ฌธ์ ๊ฐ ๋ ๊น์?
์๊ธฐ์ฌ์ฉ์ ํด๋์ค์ ๋ด๋ถ ๊ตฌํ ๋ฐฉ์์ ํด๋นํ๋ฉฐ, ์ธ๋ถ์ ๊ณต๊ฐ๋์ง ์์ ๊ตฌํ ์ธ๋ถ์ฌํญ์ ๋๋ค. ๋ฐ๋ผ์ ์์ ํด๋์ค๊ฐ ๋ถ๋ชจ ํด๋์ค์ ์๊ธฐ์ฌ์ฉ ์ฌ๋ถ์ ์์กดํ์ฌ ๋์์ ๊ตฌํํ๋ฉด ๋ค์๊ณผ ๊ฐ์ ๋ฌธ์ ๊ฐ ๋ฐ์ํ ์ ์์ต๋๋ค.
- ๋ด๋ถ ๊ตฌํ ๋ณ๊ฒฝ ์ ๋ฌธ์ ๋ฐ์:
- ๋ถ๋ชจ ํด๋์ค์ ๋ด๋ถ ๊ตฌํ์ด ๋ณ๊ฒฝ๋๋ฉด ์์ ํด๋์ค์ ๋์์ด ์๋์น ์๊ฒ ๋ณํ ์ ์์ต๋๋ค.
- ์๋ฅผ ๋ค์ด, ๋ค์ ๋ฒ์ ์์
HashSet์addAll()์ด ๋ ์ด์add()๋ฅผ ์ฌ์ฉํ์ง ์๊ณ ์ง์ ์์๋ฅผ ์ถ๊ฐํ๋๋ก ๊ตฌํ์ด ๋ณ๊ฒฝ๋๋ค๋ฉด, ์์ ํด๋์ค์์add()๋ฅผ ์ฌ์ ์ํ์ฌ ์ถ๊ฐ์ ์ธ ๊ธฐ๋ฅ์ ๊ตฌํํ ๋ถ๋ถ์ด ๋ ์ด์ ๋์ํ์ง ์์ ์ ์์ต๋๋ค.
- ์์ ํด๋์ค์ ์ฌ์์ ์๋ ๋์์ ์์กด:
HashSet์ ๊ณต์ ๋ฌธ์๋ API ์ฌ์์๋addAll()์ดadd()๋ฅผ ์ฌ์ฉํ์ฌ ๊ตฌํ๋๋ค๋ ๋ด์ฉ์ด ์์ต๋๋ค.- ์ฆ, ์ด๋ ๊ตฌํ ์ธ๋ถ์ฌํญ์ด๋ฉฐ, ์ธ๋ถ์์ ์ ์ ์๊ณ ์์กดํด์๋ ์ ๋๋ ๋ถ๋ถ์ ๋๋ค.
- ์ฝ๋์ ์ ์ง๋ณด์์ฑ ๋ฐ ์์ ์ฑ ์ ํ:
- ์์ ํด๋์ค์ ๋ด๋ถ ๊ตฌํ์ ์์กดํ๋ฉด, ์์ ํด๋์ค์ ์ ๋ฐ์ดํธ๋ ์์ ์ ์ทจ์ฝํด์ง๋๋ค.
- ์ด๋ ์ฝ๋์ ์์ ์ฑ์ ์ ํดํ๊ณ , ์๊ธฐ์น ์์ ๋ฒ๊ทธ๋ฅผ ์ ๋ฐํ ์ ์์ต๋๋ค.
- ๋ด๋ถ ๊ตฌํ ๋ณ๊ฒฝ ์ ๋ฌธ์ ๋ฐ์:
-
InstrumentedHashSet์ ์๋ฐ์์
HashSetํด๋์ค๋ฅผ ์์ํ์ฌ ์ถ๊ฐ๋ ์์์ ์๋ฅผ ์ธ๊ธฐ ์ํ ํด๋์ค์ ๋๋ค. ์ด ํด๋์ค๋ ์์๋ฅผ ์ถ๊ฐํ๋ ๋์์ ๊ณ์ธก(instrument)ํ๊ธฐ ์ํด ๋ง๋ค์ด์ก์ต๋๋ค.์ InstrumentedHashSet์ ๋ง๋ค์์๊น?
HashSet์ ์งํฉ(Set) ์๋ฃ๊ตฌ์กฐ๋ฅผ ๊ตฌํํ ํด๋์ค์ด๋ฉฐ, ์์์ ์ถ๊ฐ, ์ญ์ ๋ฑ์ ์ํํ ์ ์์ต๋๋ค. ๊ทธ๋ฌ๋HashSet์์ฒด๋ ๋ช ๊ฐ์ ์์๊ฐ ์ถ๊ฐ๋์๋์ง ์ถ์ ํ์ง ์์ต๋๋ค.์ด๋ค ์ํฉ์์๋ ์งํฉ์ ์์๊ฐ ๋ช ๋ฒ ์ถ๊ฐ๋์๋์ง ์๊ณ ์ถ์ ๋๊ฐ ์์ต๋๋ค. ์๋ฅผ ๋ค์ด, ์ค๋ณต๋ ์์๋ฅผ ์ถ๊ฐํ๋ ค๊ณ ์๋ํ ํ์๊น์ง ํฌํจํ์ฌ ์ด ๋ช ๋ฒ์ ์ถ๊ฐ ์ฐ์ฐ์ด ์์๋์ง ์๊ณ ์ถ์ ์ ์์ต๋๋ค.
์ด๋ฅผ ์ํด
HashSet์ ์์ํ์ฌInstrumentedHashSet์ ๋ง๋ค๊ณ ,add()์addAll()๋ฉ์๋๋ฅผ ์ฌ์ ์ํ์ฌ ์์๊ฐ ์ถ๊ฐ๋ ๋๋ง๋ค ์นด์ดํฐ๋ฅผ ์ฆ๊ฐ์ํค๋ ๋ฐฉ์์ ์๊ฐํ์ต๋๋ค. โฉ