제가 블로그를 시작하고 나자 대학교 후배들이 선배를 알아보고는 이것 저것 물어보는게..
수업시간에 질문하지 않는것을 미덕으로 알았던 우리시대와는 많이 다르구나 하고
새삼 세월의 차를 느꼈습니다.
그래서 예전에 제가 잡지사에 기고한 글을 검색하여 올려봅니다.
우선 제가 이 글을 쓰게 된 이유는 절대로 잘난척을 하자고 하는것이 아닙니다.
그런것이 아니라 많은 분들이 아주 중요한 점인데도 불구하고 그냥 지나치시거나 혹은
잘못된 지식을 사실인것 마냥 알고 계신것이 안타까워서 입니다.
국내에 많은 분들이 SCJP, SCJD 자격증에 도전하시거나 가지고 계시지만 이러한 기초적인
차이점을 이해하지 못하여 시험에 떨어지거나 혹은 보다 더 좋은 구조를 설계하는데에
어려움을 가지고 있음을 저는 여러번 보아 왔으며, 저도 역시 그러하였습니다.
곰곰히 그 이유가 뭔지 살펴본 결과 내릴 수 있는 결론은 프로그래머로써 가져야할
기초적인 이론을 바탕으로 하여 자신의 실력을 쌓는것이 아니라 국내의 많은 프로그래머
분들이 이론은 무시한체, 테크닉이나 단순 활용법에만 의존하며 마치 그것이 대단한
실력인양 자랑을 하는것이 문제라고 생각하였습니다.
그래서 보다 많은 분들이 좀더 체계적인 이론을 배우시기 위해서 제가 가지고 있는
몇가지 지식들을 적어보고자 합니다.
아주 밑바탕 부터 올라올 수는 없기 때문에 어느정도 중간수준에서 설명을 하도록
하겠습니다.
"이론같은것 필요없어.. 기냥 짜면 되는거지.." 라고 생각하시는 분들은 여기까지만
읽으시기 바랍니다.
<<< Extends 와 Implements 의 의미와 차이 >>>
"에이 그거다 아는 거야.. 다중상속 ... 어쩌구 저쩌구.." 라고 많은 분들이 알고
계십니다. 그러나 진정 속뜻은 진정 그렇지 않습니다.
이 차이점을 알기 전에 우리는 우선 Type 이라는 것에 대해서 알 필요가 있습니다.
Type이란 뭘까요 ?
간단하게 말하면 Type이란 어떤 놈과 다른 놈이 "다르다" 라고 말할 수 있게 하는 근거,
혹은 이유 (에구 복잡하게 말해 버렸네요..) 라고 책에는 적혀 있습니다.
만약에 우리가 길을 가다가 어떤 돌멩이 A를 주웠고, 계속 길을 가다가 동전 B를
주웠다고 합시다.
그럼 우리는 어떻게 A와 B가 다르다고 말할수 있습니까 ?
모양이 다르고, 색깔이 다르고, 무게가 다르고, 비열이 다르고, 뭐뭐뭐...
그래서 "다르다" 라고 말한다면 아주 잘 말한 것입니다.
바로 타입이라는 개념이 등장하게 됩니다.
돌멩이란 타입은 생긴것은 못생겼고, 색깔은 회색에, 비열은 뭐에..
이다. 라고 말하는 것입니다.
즉 다시 말하자면 타입이라는 것은 일종의 행동양식에 대한 반응이라고도 말 할 수
있습니다. 외부로 부터의 같은 자극에 의해서 어떤 두 물체가 다르게 반응한다면 둘은
다른 타입이 되는 것입니다.
이제 타입이라는것에 대해서 어느정도 기본 개념이 잡혔다고 보고요
그럼 객체지향 프로그래밍 언어에서 말하는 타입이란 무었인가에 대해서 말해보도록 하죠.
앞에서 말한것과 거의 비슷한 내용입니다.
결국은 행동양식, 즉 외부로 부터의 자극에 대한 반응입니다.
그럼 우리가 타입이라는 것을 정의한다는 말은 어떤 물체를 새로 만드는 것임과 동시에
그 놈의 행동 방식을 정의한다라는 말이 됩니다.
Java 에서 말하는 Interface는 바로 "새로운 타입"을 정의하는 것이 본래 사명입니다.
(Abstract Class도 여기에 해당합니다)
"어 그럼 Class는 타입을 정의하는 것이 아닌가 ?" 라고 생각하시는 분들이 계실
것입니다.
네. 완전히 틀린 말은 아닙니다. 허나 클래스는 객체를 찍어내는 풀빵틀 이 목적이지
타입을 정의하는 것은 아닙니다.
그럼 implements한다는 말은 무엇을 의미하는지 설명하도록 하겠습니다.
다시 기본적 이론을 설명하겠습니다.
객체지향에서는 어떻게 재사용성과 확장성을 보장합니까 ?
"상속" 이라고 말하시는 분들은 어느정도는 알고 계신 분들이고 "Dynamic Binding" 혹은
"Subtype Polymorphism"이라고 말하시는 분들은 정확하게 알고 계신것입니다.
여기서 우리는 한가지 분류를 해야 합니다. 상속에는 두가지 종류가 있습니다 (모르셨죠 ?)
구현의 상속과 타입의 상속입니다. 구현의 상속이 아마도 많은 분들이 이해하고 계시는
상속이며 타입의 상속은 아마도 모르고 계실것 같습니다.
그럼 타입에 대한 상속에 대해서 말씀을 먼저 드리겠습니다.
타입에 대해서는 앞에서 정의를 해드렸습니다.
그럼 이놈을 상속하겠다는 말은 즉, 어떤놈의 행동양식은 그대로 가져오되, 행동양식에
대한 반응은 재정의 하겠다 라는 말이 됩니다. 재정의 즉 오버라이딩은 바로 여기서
나오는 말입니다.
다시 말해서 타입 X가 있고, 객체 A가 있을때 객체 A가 X를 상속한다는 말은 다시
말하자면 A는 X 타입이다. 라고 말하는 것입니다. (여기까지는 그대로 가져오는
것입니다)
그리고 필요에 의해서 A가 X 타입을 나타내는 행동양식에 대해서 특별히 다르게 반응을
보인다면 그 부분만 재정의 하는 것입니다.
예를 들어 보면)
포유류 라는 타입이 있습니다.
사람도 포유류 타입입니다.
코기리도 포유류 타입입니다.
오리너구리도 포유류 타입입니다.
포유류의 행동 양식에는 "모든 포유류는 새끼를 낳는다"가 있습니다.
사람도 새끼를 낳고,
코끼리도 새끼를 낳고,
그러나 오리너구리는 알을 낳습니다.
네 그렇습니다. 오리너구리도 포유류이지만 여기서 재정의가 일어 난것 입니다.
이것이 타입의 상속입니다.
여기서 또 중요한 개념이 등장하는데 타입을 상속한 놈과 상속 당한놈과의 관계를
Subtype 관계라고 합니다.
X 라는 타입이 있고 X'이 타입 상속을 했다면 X'는 X의 서브 타입이라고 말합니다.
그리고 이때부터 바로 객체지향의 진수인 Subtyping이 가능하게 됩니다.
Subtype Polymorphism이란 기존의 수학적 모델에서는 X 타입의 자리엔 X 타입만 대입할
수 있지만 이제는 X 타입의 자리에 X의 모든 서브 타입들도 올 수 있게 하는 것입니다.
즉
X' a = new X';
X b = a;
라고 되는 것입니다.
그럼 이제서야 Implements의 의미를 알려드리게 되었습니다.
implements 한다말은 여러분이 짐작 하셨겠지만 타입을 상속하겠다는 말입니다.
(만약 일부 재정의를 하시려면 Abstract Class 를 사용하세요)
interfac Drawable {
void Draw(..);
}
이란 말은 Drawable 이란 타입을 정의하는데 그놈의 행동양식은 Draw할 수 있어야
한다라는 말입니다.
class Shape implements Drawable 이란 말은 이제부터 Shape도 Drawable 타입이란
말이며 Shape는 Drawable의 서브 타입이 되는 것이며 모든 Drawable자리에 Shape도
울 수 있게 됩니다.
이로써 재사용성과 확장성이 보장이 되는 것입니다.
그러나..
많은 OOP들에서는 타입의 상속과 구현의 상속을 구분하지 않고 있습니다. 하지만
자바에서는 Interface를 둠으로써 어느정도 구분을 하려 하였으나 역시 자바에서도
뚜렷이 구분되고 있지 않습니다.
그래서 가장 좋은 방법은 상속을 하실때는 Subtyping을 전제로 하여 하는것이 가장
좋습니다.