상속

합성

<aside> 💡

코드 재사용을 위해서는 객체 합성이 클래스 상속보다 더 좋은 방법이다

</aside>

1. 상속을 합성으로 변경하기

불필요한 인터페이스 상속 문제

메서드 오버라이딩의 오작용 문제

부모 클래스와 자식 클래스의 동시 수정 문제

1. 불필요한 인터페이스 상속 문제

public class Properties {
	private Hashtable<String, String> properties = new Hashtable<>();
	
	public String setProperty(String key, String value) {
		return properties.put(key, value);
	}
	
	public String getProperty(String key) {
		return properties.get(key);
	}
}
public class Stack<E> {
	private Vector<E> elements = new Vector<>();
	
	public E push(E item) {
		elements.addElement(item);
		return item;
	}
	
	public E pop() {
		if (elements.isEmpty()) {
			throw new EmptyStackException();
		}
		
		return elements.remove(elements.size() - 1);
	}
}

2. 메서드 오버라이딩의 오작용 문제

public class InstrumentedHashSet<E> : implements Set<E> {
	private int addCount = 0;
	private Set<E> set;
	
	public InstrumentedHashSet(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;
	}
	
	©Override public boolean remove(Object o) { return set.remove(o); }
	©Override public void clear() { set.clear(); }
	©Override public boolean equals(Object o) { return set.equals(o); }
	©Override public int hashCode() { return set.hashCode(); }
	©Override public Spliterator<E> spliterator() { return set.spliterator(); }
	©Override public int size() { return set.size(); }
	©Override public boolean isEmpty() { return set.isEmpty(); }
	©Override public boolean contains(Object o) { return set.contains(o); }
	©Override public Iterator<E> iterator() { return set.iterator(); }
	©Override public Object[] toArray() { return set.toArray(); }
	©Override public <T> T[] toArray(T[] a) { return set.toArray(a); }
	©Override public boolean containsAll(Collection<?> c) { return set.containsAll(c); }
	©Override public boolean retainAll(Collection<?> c) { return set.retainAll(c); }
	©Override public boolean removeAll(Collection<?> c) { return set.removeAll(c); }
}

3. 부모 클래스와 자식 클래스의 동시 수정 문제

class PersonalPlaylist
{
public:
	PersonalPlaylist()
		: playlist(nullptr)
	{
		playlist = new Playlist();
	}

	~PersonalPlaylist() {}

	void Emplace(const Song& song) const
	{
		playlist->Emplace(song);
	}

	void Erase(const Song& song) const
	{
		std::erase(playlist->GetTracks(), song);
		playlist->GetSingers().erase(song.GetSinger());
	}

private:
	Playlist* playlist;
};

2. 상속으로 인한 조합의 폭발적인 증가

1. 기본 정책과 부가 정책 조합하기

image.png

image.png

기본 정책의 계산 결과에 적용된다

선택적으로 적용할 수 있다

조합 가능하다

부가 정책은 임의의 순서로 적용 가능하다

2. 상속을 이용해서 기본 정책 구현하기