ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • '오브젝트' 책 보고 공부하기 - ⑫ 다형성
    JAVA공부/JAVA 2023. 6. 25. 01:26

    1) 다형성

     

    다형성많은 형태를 가질 수 있는 능력을 의미한다.

    프로그래밍에선 여러 타입을 대상으로 동작할 수 있는 코드를 작성할 수 있는 방법으로 얘기할 수 있다.

     

    다형성의 분류

    • 유니버설
      • 매개변수
        제네릭 프로그래밍과 관련이 높은데, 인스턴스 변수 혹은 메서드의 매개변수 타입을
        임의의 타입으로 선언 후 사용시점에 구체적인 타입으로 지정하는 방식

      • 포함
        메시지가 동일하더라도 수신한 객체의 타입에 따라 실제로 수행되는 행동이 달라지는 능력
        (서브타입 다형성)

    • 임시
      • 오버로딩
        하나의 클래스 안에 동일한 이름의 메서드가 존재하는 경우(시그니처만 다름)

      • 강제
        언어가 지원하는 자동적인 타입변환이나 사용자가 직접 구현한 타입 변환을 이용해 
        동일한 연산자를 다양한 타입에 사용할 수 있는 방식
        (단, String + 정수형을 하면 String이 나오는 것처럼 어떤 메서드가 호출될지 알기 모르기 때문에 조심)

     


     

    2) 상속의 양면성

     

    상속의 목적은 코드 재사용이 아니라 다형성을 가능하게 하는 타입계층을 구축하기 위한 것

     

    자식 클래스 안에 상속받은 메서드와 동일한 시그니처의 메서드를 재정의해서 부모클래스의 구현을 새로운 구현으로

    대체하는 것을 메서드 오버라이딩이라 한다.

    메서드와 이름은 동일하지만 시그니처는 다른 메서드를 자식클래스에 추가하는 것을 메서드 오버로딩 이라고 한다.

     

    데이터 관점의 상속은  개별 인스턴스로서 상태를 관리하고 있으며

    행동관점의 상속을 보면 개별 인스턴스들의 클래스가 가지고 있는 메서드를 하나로만 관리하고 있다.

    (물론 언어마다 다르겠지만, JVM은 클래스 로드시에 Method Area에 메서드들을 보관한다고 한다.)

     


     

    3) 업캐스팅과 동적 바인딩

     

    부모 클래스타입으로 선언된 변수에 자식 클래스의 인스턴스를 할당하는 것을 업캐스팅이라 한다.

    이런 특성을 대표적으로 사용할 수 있는 곳이 대입문과 메서드 파라미터 타입이다.

    반대로 부모 인스턴스를 자식 클래스 타입으로 변경하기 위해서는 명시적인 타입 캐스팅이 필요한데,

    이를 다운캐스팅이라 한다.

     

    선언된 변수의 타입이 아니라 메시지를 수신하는 객체의 타입에 따라 메서드가 결정 되는 것을 동적 바인딩이라 한다.

    전통적인 언어들은 코드를 작성하는 시점에 호출될 코드가 결정되는데

    이를 정적 바인딩, 초기바인딩, 컴파일타임 바인딩이라고 한다.

     

    객체지향 언어에서는 실행시점에 어떤 클래스의 인스턴스를 생성해서 전달하는지 알아야만

    실제로 실행되는 메서드를 알 수 있다.

     

     


     

    4) 동적 메서드 탐색과 다형성

     

    객체지향에서의 메서드 탐색은 다음과 같다.

    자신을 생성한 클래스에 적합한 메서드가 있는지 확인 -> 부모 클래스에서 메서드 탐색(상속 계층 탐색) -> 미존재시 예외

    객체가 메시지를 수신하면 컴파일러는 self 참조라는 임시 변수를 생성한 후 메시지를 수신한 객체를 가리키도록 한다.

    메서드 탐색 종료 후 해당 참조는 자동 소멸된다. (자바에서는 this)

    시스템은 class포인터(클래스정보 로드 가능), parent 포인터(상속정보 로드 가능)와 함께 

    self참조를 조합해서 메서드를 탐색한다.

     

    동적 메서드 탐색은

    자동적인 메시지 위임 - 상속관계를 올라가면서 메서드 탐색

    동적인 문맥 -  실행 시점에 어떤 객체에 의해 이뤄질 것인지 self참조를 이용해 결정

    으로 이루어진다.

     

    동적 메서드 탐색으로 인해 메서드 오버라이딩시 self참조의 객체의 메서드가 우선실행된다.

    self전송은  자신에게 다시 메시지를 전송하는 것을 말하는데, 상속관계에서는 이 메시지가 어디에 존재하지 모르기 때문에

    상속계층들을 전부 살펴보아야 할 수도 있는 어려운 코드가 만들 어 질 수 있다.

     

    정적타입 언어에서는 코드를 컴파일 할 때 상속 계층안의 클래스들이 메시지 이해할 수 있는지 여부를 판단하고

    이해하지 못하는 경우 컴파일에러를 발생시킨다.

     

    동적타입 언어에서는 메시지를 실행 한 후에야 메시지 처리 가능 여부를 알 수 있다. 사실 이는 조금 더 객체지향적이라 

    볼 수 있는데, 내부구현을 모른채 메시지를 처리할 수 있다고 믿고 전송하기 때문이다.

    또한, 메타 프로그래밍 역역에서도 진가를 발휘하며, 정적언어보다 더 쉽고 강력한 도메인 특화 언어를 개발할 수 있다.

     

    자식클래스에서 부모 클래스의 구현을 재사용해야하는 경우가 있는데, 이 때 super참조를 이용할 수 있다.

    이때 super.method()를 하는 것은 메서드를 '호출' 하는 것이 아니라 '전송'하는 것이다.

     

     

     


     

    5) 상속 대 위임

     

    객체가 다른 객체에게 요청할 때 인자로 self참조를 전달하면 위임, 전달하지 않으면 포워딩이라고 한다.

    위임을 통해 상속과 유사한 코드를 만들 수 있다. 즉 위임을 통해 클래스를 이용한 상속관계를 객체사이의 합성관계

    대체해서 다형성을 구현한다.

    상속의 장점은 이 위임을 하기 위한 메서드들을 손수 작성하지 않아도 된다는 점이다. (자동적인 메시지 위임 처리)

     

    프로토타입 기반 객체지향 언어는 클래스가 존재하지 않고 객체만 존재하는데, 상속을 구현하는 유일한 방법은

    객체 사이의 위임을 이용하는 것이다. (ex]자바스크립트)

    책에서 보여주는 자바스크립트 예시는

    1.객체지향 패러다임에서 클래스가 필수 요소가 아니다.

    2.상속 이외의 방법으로도 다형성 구현이 가능하다.

    3.객체지향은 객체를 지향하는 것이다.

    4. 객체 사이의 자동적인 메시지 위임을 통해 상속을 이뤄낼 수 있다.

    를 알려준다.

     

     

     

Designed by Tistory.