Implement가 뭐에요?

JAVA : 2008.01.07 20:07

출처 모름

우선 제가 이 글을 쓰게 된 이유는 절대로 잘난척을 하자고 하는것이 아닙니다.

그런것이 아니라 많은 분들이 아주 중요한 점인데도 불구하고 그냥 지나치시거나 혹은
잘못된 지식을 사실인것 마냥 알고 계신것이 안타까워서 입니다.

국내에 많은 분들이 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을 전제로 하여 하는것이 가장
좋습니다.

-------------------------------------------------------------------------------

우선, extends는 일반 클래스와 abstract클래스 상속에 사용되고, implement는 interface상속에 사용됩니다.

그럼, 상속이라는것은? 나의 부모가 부자라면, 내가 부모로부터 상속 받는 다면 나도 부자가 됩니다. 결국, 다른것으로부터 그들의 기능을 빌려다 쓴다고 생각하시면 됩니다. 자바에서의 상속은 2가지 형태가 있습니다.
하나는 extends 이고, 다른 하나는 implements인데, 첫번째는 순수 상속으로 앞에 설명 드린것처럼, 부모로부터 모든 권한과 재산과 능력을 가져 옵니다. 다른 하나는 구현상속, 이라고 합니다. 구현상속 ==> 인터페이스라고 흔히 하죠. 상속이라기 보단. 인터페이스만을 얻어 오는 겁니다. 쉽게 얘기해서, 무언가로 부터 상속은 받되, 그 상속 내용이 란게 비어 있고, 그 비어 있는 것을 내가 꼭 채워서 써야 하는 것을 의미합니다. [소스2]는 childclass2 가 TestInterface을 상속받아서 implement 했다고 생각하시면 됩니다.

다른 비유로 설명한다면, implement(구현 상속)은 조언자로 부터 조언자가 잡은 고기를 얻는게 아니라, 고기를 잡는 방법을 얻어 온다고 생각하시면 됩니다.

그럼 실례로 들어서 생각해 봅시다. 누군가가 나에게 사용자가 입력한 내용을 파일로 저장하는 모듈을 만들어 달라고 했습니다. 파일 저장형식은 1) 엑셀, 2)html, 3)텍스트 세가지의 형식으로 저장 가능하도록 해야 한다고 할때, 개발자는 3가지의 기능이 각기 서로 상이 하므로 서로다른 3개의 모듈을 만들것 입니다. 하지만, 이 모듈을 정작 사용하는 입장에서는 3개의 모듈이 모두 같은 인터페이스를 제공 해주길 바랄것입니다. 결국 자바 클래스관점에서 본다면, 서로 다른 모듈이 하나의 인터페이스로 부터 구현 상속을 받아 야 할것 입니다. 그러면, 사용자는 그 하나의 인터페이스만 보고, 코딩을 하면 될테니까요.

더 쉽게 설명 드리면,
extends: 부모로 부터 상속, implements: 조언자로 부터 상속이라고 보시면 됩니다.

세상의 모든 자식들은 하나의 부모만을 가집니다. 결국, extends을 사용해서, 차일드는 단하나의 부모로 부터 상속 받을 수 있다는거죠. 그럼, 조언자는요? 세상을 살아가는 데 여러 조언자를 만날수 있습니다. 그들은 고기 잡는 법만 알려주죠. 그들이 조언한 방식을 내나름대로 실천하는 게 바로 구현상속(implements)가 되는거죠. 결국, implements을 사용해서, 차일드는 여러 조언자를 만날수 있습니다. 그리고, 조언자는 차일드 윈도우에게 뭔가를 주는 입장이 아니므로, 모두들 interface클래스 이어야 합니다. 즉 방법만 있고, 내용이 없는 거죠.



[소스1]
public interface TestInterface {
public static int num = 8;
public void func1();
public void func2();
}
public class Test {
public void func2() {
System.out.println("func2");
}
}

[소스2]
class childclass1 extends Test{

public void func1() {
System.out.println("fun1.");
}

}

class childclass2 implements TestInterface {
public void func1() {
System.out.println("Class Test1");
}
public void func2() {
System.out.println("Class Test2");
}
}

'JAVA' 카테고리의 다른 글

package와 import문의 사용  (0) 2009.07.21
Implement가 뭐에요?  (0) 2008.01.07
자바 참고 ( 이클립스 -> jsmooth -> exe 과정)  (0) 2007.10.27
RoboCode  (0) 2007.06.14
Posted by Real_G