1. 소개 ¶
요즘 심심하면 이상한 책들을 보는데 이런 이야기가 나와서 소개할만한 가치가 느껴지므로 적음.
(심심하면 아래를 읽을 것 -_-; 오로지 코드에만 관심있는 사람이라면 BACK 버튼을~ 별로 재미없는 내용으로 이어질 것으로 보임)
(심심하면 아래를 읽을 것 -_-; 오로지 코드에만 관심있는 사람이라면 BACK 버튼을~ 별로 재미없는 내용으로 이어질 것으로 보임)
객체 지향에서 가장 중요한 개념을 꼽으라면 무엇을꼽을까?
다름 아닌 다형성(Polymorphism)이라고 하지 않을까 싶다.
다름 아닌 다형성(Polymorphism)이라고 하지 않을까 싶다.
이 다형성에도 종류가 있다는 것을 알려는지 모르겠다.
첫째는 최초로 제안된 다형성인 ParametricPolymorphism, 둘째는 어쩌다 생겨나 버린 Ad-hocPolymorphism 이렇게 두가지가 존재한다.
한번 개념의 차이를 이해하고 자바5에서 지원하기 시작한 generic의 도입의 의미에 대해서 생각해보는 시간이 될 것이다.
첫째는 최초로 제안된 다형성인 ParametricPolymorphism, 둘째는 어쩌다 생겨나 버린 Ad-hocPolymorphism 이렇게 두가지가 존재한다.
한번 개념의 차이를 이해하고 자바5에서 지원하기 시작한 generic의 도입의 의미에 대해서 생각해보는 시간이 될 것이다.
그리고 내용이 대부분 책에 있는 내용에서 필요한 부분만 간추린 내용이라 생략된 부분이 존재하니
읽어보고 싶은 사람은 도서관에서 찾아서 읽어보면됨. (몇장안됨)
읽어보고 싶은 사람은 도서관에서 찾아서 읽어보면됨. (몇장안됨)
ps. ㅡ.ㅡ;; 우리는 저거까지 배우지도 않았는데... 역시 학교수업이란 ㅉㅉ
2. 다형성? ¶
차를 생각해보자. 우리 주변의 차는 정말로 많다.
그중 차들을 추상화하여 표현한 명사 Car, 그것의 하위의 것들은 sportCar, luxuryCar 이렇게 3개의 객체를 생각해보자.
당연히 후자의 2개의 객체는 전자의 2개의 객체를 상속한다.
당연히 Car 와 sportCar, luxuryCar 는 서로 동일한 원리로 움직이겠지만 동일하지는 않다.
getCar(:String):Car 라는 메소드를 생각해보자.
~cpp public Car getCar(String clientType) { if("young man".equals(clientType)) { return new SportCar(); } else if("old man".equals(clientType)) { return new LuxuryCar(); } else { //Error! return null; } }
상기 메소드를 통해서
~cpp Car sportCar = getCar("young man"); Car luxuryCar = getCar("old man");의 식을 쓸 수 있다.
그리고 위와 같은 것으로 현재 다형성이라고 하는 방식이 구현되어져 있다.
동일한 Car이기는 하지만 run()이라는 메시지를 2개의 각기 다른 차에 주면 당연히 한차는
엄청난 가속도로 속도가 붙어서 달리기겠지만 다른 차는 가속도보다는 승차감이라든가 그외적 요소에 더욱
신경을 쓴 run()이라는 방식으로 달리게 될 것이다.
대략 이것이 다형성이라는 것으로 표현된다.
3. Parametric Polymorphism ¶
본디 폴리모피즘에서 추구한 방식 즉 파라메트릭 방식에 의하면 상기의 식을 적용할 때 동적 캐스팅이 필요가 없어야한다.
자 스포츠 카에 터보엔진이 달렸다는 발상을 해보자.
~cpp Car sportCar = getCar("young man"); sportCar.startTurboEngine();어떨까?
당연히 에러가 난다. 터보엔진은 스포츠 카에 달린 것이지 Car라는 객체에는 존재하지 않기 때문이다.
그렇다면 다음은?
~cpp SportCar sportCar = getCar("young man"); sportCar.startTurboEngine();역시 에러가 난다. SportCar에 대입되는 getCar():Car는 SportCar보다 상위의 개념은 Car이기 때문이다.
이를 해결한 코드는 다음과 같다.
~cpp SportCar sportCar = (SportCar) getCar("young man"); sportCar.startTurboEngine();에러는 피했다. 하지만 우리가 그리도 바라마지 않던 품격의 객체지향 언어가 너덜너덜한 표현법을 쓴다.
본디 파라메트릭 폴리몰피즘은 상기와 같은 문제의 해결을 위해서 방어적 수단을 제공한다.
무엇인고 하니, 바로 리턴해야할 객체의 타입을 인수로 준다는 개념이다. (C++의 템플릿 같지?)
위와 같은 개념의 코드로 작성이 되면 동적 캐스팅이 필요 없을뿐만아니라 잘못된 타입 캐스팅으로 인한
에러역시 방지할 수 잇다.
최근 자바 5 에서는 generics 라는 기능을 도입함으로서 파라메트릭 폴리모피즘을 지원하기 시작했다.
generics에 대한 예제
~cpp class Pair<SomeObjectType> { SomeObjectType x, y; Pair(SomeObjectType x, SomeObjectType y) { this.x = x; this.y = y; } SomeObjectType getFirstObject (Pair<SomeObjectType> p) { return p.x; } }
상기와 같은 방식으로 작성하게 되면 다음과 같이 특정한 데이터 형에 구애 받지 않는
로직이 작성된다.
~cpp Pair<Integer> p; p = new Pair<Integer>(new Integer(0), new Integer(1)); Integer x = p.getFirstObject(p); Pair<Boolean> p; p = new Pair<Boolean>(new Boolean(0), new Boolean(1)); Boolean x = p.getFirstObject(p); . . . .
이렇게 파라메트릭 폴리모피즘을 도입함으로서 좀더 우아한 코드가 완성된다.