이번 시간에는 참조형에서의 upcasting에 대해 알아보도록 하겠습니다. 그리고 다형성에 대해서 간략하게 논해보도록 하겠습니다.

 

 


 먼저 예제 프로그램을 보겠습니다.

 

 Animal 클래스와 Animal을 상속받은 dog와 cat이 있습니다. dog와 cat은 오버라이딩이 된 speak 메서드를 가지고 있습니다.

 

 

 Main 메서드는 위와 같습니다. 프로그램의 실행 결과는 어떻게 나올까요?

 

 

 분명히, 저는 Animal 참조 변수 dog1과 cat1의 speak 메서드를 수행하였습니다. 그런데, 실행 결과는 I'm dog, I'm cat이 나옵니다. I'm animal이 아니라요. 동일한 type이지만, 다양한 결과가 나왔습니다. 이를 다형성이라고 합니다. 그런데, 우리는 dog나 cat을 참조하는 참조 변수 값을, Animal 참조 변수에 대입을 했는데. 이건 문제가 없을까요?

 

 


 이렇게 한 번 생각해 보겠습니다.

 

 별 문제가 없어 보입니다. 왜냐하면, Animal 집합에 Dog가 포함되기 때문입니다. 다시 말해 개는 '동물' 이라는 것은 항상 참이 됩니다. 반대로, 동물은 '개'라는 명제는 참이 되지 않습니다. 개일 수도 있지만, 그렇지 않을 수도 있기 때문입니다. 자식 타입을 부모 타입으로 변환하는 것을, 업캐스팅이라 이야기 합니다. 그 반대의 경우를 downcasting이라고 하는데, 이것은 조심해야 합니다. 왜냐하면, 동물이 '개'라는 것이 보장되지 않기 때문입니다. 그런데 굳이, Dog d = new Dog(); 이렇게 써도 되지 않을까요? 그리고 d.speak(); 를 호출해서 나는 개라는 메세지를 호출하게 하면 되지 않을까요?

 

 

 위 질문에 대해서 해결하기 위해서 먼저, 이 둘의 차이점에 대해 간단하게 짚고 넘어가겠습니다. 먼저, 1번째 문장은 크게 어렵지 않습니다.

 

 

 dog 타입의 참조 변수가 dog 객체를 가리킵니다. 문제는 2번째인데요.

 

 

 new dog()의 값을 d1에 넣었으니까, d1은 새롭게 생성된 dog 객체를 가리키기는 합니다. 문제는 d1이 Animal 객체를 참조하는 변수라는 것입니다. 기본적으로 필드들은, static binding이 되니, d1.필드 이름으로 접근을 하면, Animal의 필드 이름으로 접근할 겁니다.

 

 문제는, overriding이 된 함수인데요. d1.speaking을 호출하게 되면, 일단 이 함수는 Animal 클래스에도, 다른 동물 클래스에도 있습니다. 실제로 Animal을 참조한다는 참조 변수 d1은, dog 객체를 참조하기 때문에 runtime에 강아지 객체의 speak가 호출이 됩니다.

 

 

 즉, speak가 Animal에도 있고, 자식 클래스에 overriding이 되어 있을 때, 어떤 method를 선택할 것인지는 runtime에 결정이 된다는 것입니다. 이제, 다음 문장을 보도록 하겠습니다.

 

 

 이것은 어떨까요? c1은 Animal을 참조하는 변수입니다만, 실제로는 새로 생성된 Cat 객체를 가리키고 있습니다.

 

 

 c1은 실제로 cat 객체를 참조하고 있습니다. 그렇기 때문에, 나는 고양이다라는 문구를 출력합니다.

 

 


 같은 참조형이지만, speak를 불렀는데, 분명히 다른 동작을 하고 있습니다. '다형성' 이라고 합니다.

 

 

 그러면 이런 것을 왜 쓸까요? 그냥 각 객체별로 speak라는 것을 따로 구현해야 하는 건 똑같아 보이는데. 차량 정비소 클래스를 생각해 봅시다. 바퀴 휠을 간다고 생각해 봅시다. 예를 들어 A형, B형, C형 이런 것들이 있을 겁니다. 이런 질문을 역으로 던질 수 있습니다.

 

 

 정비소 클래스에서는 그냥 Wheel 클래스에서 휠을 빼고, 끼우는 메서드만 호출하면 됩니다. Wheel 클래스가 타이어와 분리하는 메서드와, 타이어와 결합하는 메서드가 있고, A, B, C형이 Wheel의 타이어와 분리/결합 기능을 구현한다면 가능한 이야기가 되어버립니다.

 

 단지, 우리는 Wheel이라는 매개자를 통해서, 분리, 결합하는 기능을 호출하면 됩니다. A, B, C형이 있다는 것을 몰라도 됩니다.