안녕하세요 코딩도장 덕분에 재밌게 공부하고 있습니다. 한 가지 질문 드립니다.
36.2.1에서 '상속은 명확하게 같은 종류이며 동등한 관계일 때 사용합니다.' 라고 배웠는데요
36.5에서 나온 예문을 보면 대학생(Undergaduate)이 사람(Person)과 대학교(University)를 다중상속하고 있습니다.
'대학생은 사람이다'는 말이 되지만
'대학생은 대학교다'는 말이 안 되는 것 같은데 어떻게 상속이 가능한 걸까요?
class Person:
def greeting(self):
print('안녕하세요.')
class University:
def manage_credit(self):
print('학점 관리')
class Undergraduate(Person, University):
def study(self):
print('공부하기')
james = Undergraduate()
james.greeting() # 안녕하세요.: 기반 클래스 Person의 메서드 호출
james.manage_credit() # 학점 관리: 기반 클래스 University의 메서드 호출
james.study() # 공부하기: 파생 클래스 Undergraduate에 추가한 study 메서드
빠른 답변 감사합니다.
36.2.2 강의 내용에 '같은 종류에 동등한 관계일 때는 상속을 사용하고, 그 이외에는 속성에 인스턴스를 넣는 포함 방식을 사용하면 됩니다'라고 되어 있어서 has-a 관계는 상속을 하면 안 되는 것으로 이해하고 있었습니다. 결국 has-a 관계라도 상속은 가능하다는 말이네요!
네, 가능합니다.
자바 같은 언어는 다중 상속을 금지시켰지만,
정확하게 말하면 is-a 관계만 상속을 사용하고
has-a 관계라고 보이면 인터페이스를 쓰라는 식이죠.
그래서 자바에서도 인터페이스는 다중 상속을 합니다.
public class ArmoredCar extends Car implements Floatable, Flyable
Car 클래스를 상속한 ArmoredCar 클래스를 만들지만,
인터페이스 Floatable, Flyable을 상속받습니다.
자바에서는 클래스 상속과 인터페이스 상속으로 분리되어 있습니다.
ArmoredCar is a Car이고
ArmoredCar has a Floatable, Flyable일 겁니다. 물에서도 뜨고, 하늘도 날 수 있는 기능을 갖고 있겠지요.
이처럼 기능을 갖고 있다면 기능은 인터페이스 상속으로 쓰라는 것입니다. 객체 지향에 대한 이해가 낮을 때는 클래스 상속으로 기능을 상속하는 경우도 많았는데, 그런 거 하지 말라고 언어 차원에서 강제한 것이 자바 같은 언어입니다.
C++는 왜 개발자에게 그런 것을 강제하고 강요하느냐, 우리는 다 열려 있고, 쓰는 건 개발자의 몫이다... 라는 뜻입니다.
Go, Rust 같이 훨씬 더 나중에 생긴 언어들은 프로그래머의 실수를 방어하기 위해 더 많은 것들을 강제하고 있습니다. Go 언어는 gofmt로 코딩 스타일도 강제해버립니다. 나는 탭, 난 들여쓰기 3칸, 난 4칸... 이런 것조차 허용하지 않습니다.
그래서 과거 언어일수록 자유도가 높지만, 똥 코드를 만들기 쉽고, 피해야 할 똥을 많이 알아둬야 합니다. 현대 언어일수록 자유도는 낮지만, 애초에 똥 코드 작성을 막아버렸기 때문에 똥 코드가 생성될 일이 없고, 볼 일도 없는 게 추세입니다.