객체지향 언어의 설계 이슈
원 객체를 도형 크기의 칸에 넣으면 무슨 일이 생길까?
서브클래스는 서브타입인가
원은 도형이다
덮어쓰는 것은 괜찮습니다. 부모 자리에서 하던 호출이 그대로 통하게, 곧 호환되게 덮어쓰면 그 서브클래스는 서브타입(subtype)입니다. '원은 도형이다'라는 is-a 관계가 성립합니다.
서브타입이 되려면 변수와 메서드를 더하고, 물려받은 메서드는 호환되게만 덮어써야 합니다. 매개변수는 메서드가 받는 값입니다.
단일 상속과 다중 상속
부모가 둘이면 이름이 부딪힙니다
부모가 하나면 단일 상속(single inheritance), 둘 이상이면 다중 상속(multiple inheritance)입니다. 다중 상속은 편리할 때가 있지만, 이름이 부딪혀 언어와 구현이 복잡해집니다.
RoundRect는 예시입니다. 교재의 예는 Thread와 Drawing을 함께 물려받는 DrawThread입니다.
객체의 할당
객체를 스택에 둘까, 힙에 둘까
객체도 메모리 칸을 받아야 합니다. 스택에 통째로 놓을 수도 있고, new로 힙에 만들어 참조로 가리킬 수도 있습니다. 참조는 객체를 가리키는 값입니다.
모든 객체를 힙에 두는 언어는 객체를 언제나 참조로 다룹니다. 값은 예시입니다.
객체 슬라이싱
부모 크기의 칸에 넣으면 잘립니다
스택에 직접 두면 Shape 변수의 칸은 Shape 크기만큼만 잡힙니다. 더 큰 Circle 객체를 대입하면 radius는 잘려 나갑니다. 이것이 객체 슬라이싱(object slicing)입니다.
C++에서 객체를 스택에 둘 때 생기는 일입니다. 힙에 두면 참조만 복사되어 잘리지 않습니다.
객체의 해제
다 쓴 객체는 누가 치울까
객체가 차지한 칸을 돌려주는 해제도 정해야 합니다. 프로그래머가 문장으로 적는 명시적 해제가 있고, 언어가 알아서 하는 묵시적 해제가 있습니다.
가비지 컬렉터는 4강에서 본, 더는 쓰이지 않는 칸을 찾아 대신 돌려주는 장치입니다.
중첩 클래스
한 곳에서만 쓰면 안에 넣습니다
한 클래스 안에서만 필요한 클래스는 그 안에 넣어 다른 클래스에게 감춥니다. 이것이 중첩 클래스(nested class)입니다. 안팎이 서로의 멤버를 어디까지 보게 할지가 설계 이슈입니다.
멤버는 클래스에 든 변수와 메서드입니다.
객체 초기화
만들 때 부모 부분부터 채웁니다
객체를 만들 때 값을 채우는 일이 초기화입니다. 서브클래스의 객체는 물려받은 부분도 채워야 하므로, 보통 부모 클래스의 생성자가 먼저 불립니다.
생성자(constructor)는 10강에서 본, 객체가 만들어질 때 불려 처음 값을 넣는 메서드입니다. 언어가 기본값을 넣어 주는 초기화도 있습니다.
다음 편