ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • Java: 다형성을 '정말' 이해하기 위해서
    Java 학습 2022. 5. 13. 12:58

    Java: 다형성을 '정말' 이해하기 위해서

    들어가기 앞서


    다형성의 기초적인 개념을 설명하는 글이 아니지만, 다형성을 이해하는 데에 있어서 꼭 필요하다고 생각되는 부분을 나름대로 정리해보려고 한 글이다.
    본 내용은 아래 파트에서 설명한다. 이 파트는, 왜 그 알아듣기도 어려운 설명을 꼭 들어야하는지에 대한 나의 생각이다.
    그럼 그게 어떤 생각인지, 한번 이야길 해보자.

    다형성은 특정한 로직 구성 방법을 말하는 것이 아니다.
    다형성은 개념이다.

    우리가 자연수를 설명한다고 해보자. 자연수는 '특정한 수'가 아니고 '개념'이다.
    이 개념을 설명하기 위해서는 '0보다 큰 정수'라는 개념을 알려줘야만 한다. 그 설명을 듣고 바로 이해가 되지 않더라도, 그렇게 설명해줘야만 한다.
    자연수를 설명하면서 쉽게 이해하라고,

    1이란 숫자는 바로 자연수야.
    2도 자연수야.
    3의 경우도 자연수라고 할 수 있어.
    4도 마찬가지로 자연수야.
    그밖에도 더 많은 자연수들이 있으니까 참고해~

    라고 하면 그건 맞는 설명이면서도 '알려주는 설명'으로는 턱없이 부족하다. 쉽게 이해한 것도 의미가 없는게, 이런 설명을 듣고 자연수를 배운 사람은 필연적으로 이런 의문으로 이어질 수밖에 없다.

    그럼 10은 자연수야?
    12는?
    100은?
    혹시 100000000000000000000000은 자연수 아니겠지? 얘는 엄청 크니까?

    자연수 '개념'을 설명하기 위해서 '특정한 예시'만을 설명에 이용하면, 학생은 '자연수 자체'를 이해하기 위해서 결국 시간낭비라는 부작용을 겪게 되는 것이다.

    다시 다형성의 예로 돌아와보자.

    Coffee coffee = new Americano();처럼 쓰는게 다형성이야.

    라고 말한다면 그건 부족한 설명이다. 또 하나 있는데

    다형성(polymorphism)이란 하나의 객체가 여러 가지 타입을 가질 수 있는 것을 의미합니다.

    라는 설명도 마찬가지다. (구글링하면 다 이 얘길 하고 있는데, 다들 이 문구를 어디서 복사해오는 건지 모르겠다....)

    자, 한 번 보자.

    • buyCoffee(Coffee coffee)라는 메소드의 파라미터로 new Americano()를 넘겨주는 코드는 다형성을 적용한 코드는 다형성을 적용한 걸까, 아닌걸까? 이 코드도 다형성을 적용한 사례다.
    • 또, Coffee class의 생성자를 public Coffee(), public Coffee(Coupon coupon), public Coffee(boolean isDripCoffee)와 같이 오버로딩 했다면? 이 코드도 다형성을 적용한 사례다.
    • 그리고 또, Map 인터페이스의 구현체 MyMap 객체를 구현했다면? 이것도 다형성을 적용한 사례다.
    • 그리고 또한, Object에서 물려받은 toString() 메소드를 현재 객체에서 오버라이드 했다면? 이것도 다형성을 적용한 사례다.
    • 그리고 그리고 또 또한, ....





    그럼 다형성 '개념'을 잘 설명해달라구웃


    지금부터의 설명은 곧장 이해되지 않아도 좋다. 들어만 놓고 지나가도 상관없다. 이도 저도 싫으면 굵은 글씨만이라도 읽자.

    Java를 비롯한 OOP의 핵심 컨셉트는 '메시지(Message)'다. 다형성 또한 메시지 개념이 있어야 이해하기가 쉽다. 아니, OOP로 구현되는 모든 로직은 메시지에 대한 이해를 기반으로 한다. 훌륭한 시스템을 만드는 핵심은 모듈 간의 커뮤니케이션에 달려있다(Alan Kay 교수의 본문).

    OOP는 무언가와 무언가 사이에, 어떤 방식으로든 연관을 만들어가며 시스템을 구성한다.

    이렇게 코드 안에서 연관을 만들어가는 것─new하며 생성자를 호출하는 것도, 타입과 인스턴스를 연결하는 것도, 메소드를 호출하고 결과값을 받는 것도 각 class 안에 정의된 자원을 호출함으로써 구성되는 것이다. (메시지에 대해 잘 이해가 안되었다면, 이 '호출'들을 메시지라고 생각하자)

    다형성이란, 동일한 메시지로도 상황에 맞는 적절한 의도로 처리/전달될 수 있게 하는 특성이다.

    • Coffee 타입이 언제는 Coffee 본인, 언제는 Americano, 언제는 Latte로 구현될 수 있는것? 다형성이다.
    • toString() 메소드가 배열객체에서 'toString()'할 때는 [1,2,3, ...], 문자열 관련 객체에서 'toString()'할 때는 "문자열", 일반 객체에서 'toString()'할 때는 클래스@메모리주소로 출력되는 것? 동일하게 'toString()'하고 있음에도 다른 결과물의 형태를 보여주는 것? 다형성이다.
    • 똑같은 생성자 Coffee()를 호출하면서 다른 관계를 가질 수 있도록 Coffee(), Coffee(1), Coffee("arabica")로 구분해서 호출하도록 하는 것? 다형성이다.

    핵심은 이처럼 똑같은 이름, 똑같은 타입, 똑같은 시그니처로 호출을 하는 것, 한 마디로

    나는 똑같은 말을 했는데, 시스템에서 구성한 의도에 따라 자연스럽게 처리가 되는 것

    이다. '어떻게 수행해줘!'를 구체적으로 말하지 않아도 '어떻게 잘' 수행해주는 것이다.
    이것에 대한 좀 더 자세한 예시는 전에 작성한 글의 일부분(여기서도 특징 - '다형성' 파트)을 참고하자.

    이렇게 하면 뭐가 좋은데?


    신기하든 어쩌든 좋은 점이 있어야 쓸 수 있는거 아니겠는가?
    하지만 안타깝게도 장점은 지금 구체적인 예를 들어 설명하기가 어렵다.
    다형성은 자바 전반에 영향을 미치는 아주 중요한 특성이기 때문에, 자바를 한바퀴 돌며 쭉 둘러보고 나서야, 전반에 걸쳐있는 다형성의 거대한 장점을 이해할 수 있게 되는 것이다. 외울 필요도 없다.

    잘 짜여진 자바 코드는 객체 간의 책임과 역할을 어떻게 구분하는가, 책임을 결정하는 주도권을 어디에 두는가.

    그런 것들을 공부하게 될 때, 어떤 순간, 놀라운 천재들이 준비해놓은 이 개념에 저절로 감탄하기만 하면 된다.

    'Java 학습' 카테고리의 다른 글

    변수의 종류(type)의 기초적인 이해  (0) 2022.05.04
    Java 프로그램의 기본 구성  (5) 2022.05.04

    댓글

Designed by Tistory.