본문 바로가기
프로그래밍/Java

[실전 자바-기본편] 다형성

by Dean30 2024. 2. 21.
728x90

객체지향 프로그래밍의 대표적인 특징은 캡슐화, 상속, 다형성이 있다. 그 중 다형성은 객체지향 프로그래밍의 꽃이라 불린다.

앞서 학습한 캡슐화, 상속은 직관적으로 이해하기 쉽다.

반면 다형성은 제대로 이해하기 어렵고, 잘 활용하기는 더 어렵다.

 

다형성(Polymorphism)

  • 다양한 형태, 여러 형태
  • 프로그래밍에서 다형성은 한 객체가 여러 타입의 객체로 취급될 수 있는 능력을 뜻한다.
  • 다형성 이해를 위한 핵심 이론
    • 다형적 참조
    • 메서드 오버라이딩

 

다형적 참조

  • 부모 타입의 변수가 자식 인스턴스를 참조한다.(할당으로 이해하기)
    • = 부모는 자식을 담을 수 있다.
      • 부모는 마음이 넓다.
      • 반대로 자식 타입은 부모 타입을 담을 수 없다.
    • Parent poly = new Child();
      • 캐스팅과 다름 !
    • Child 인스턴스는 메모리 상에 Child와 Parent가 모두 생성된다.

 

 

 

다형적 참조의 한계

  • Parent poly = new Child()인 상황에서
    • poly가 자식 타입인 Child에 있는 childMethod()를 호출 불가
    • poly.childMethod() 실행 시 먼저 참조값을 통해 인스턴스를 찾는다.
    • 그 다음 인스턴스 안에서 실행할 타입을 찾아야 하는데 poly가 Parent 타입이므로 Parent부터 찾는다.
    • 그런데 상속 관계는 부모 방향으로 찾아 올라갈 수는 있지만, 자식 방향으로는 찾아 내려갈 수 없다.
      • 컴파일 오류가 발생한다.

 

 

 

 

다형성과 캐스팅

 

  • Parent poly = new Child()
  • Child child = (Child) poly // 다운 캐스팅 !!
    • 캐스팅 한다고 해서 Parent poly의 타입이 변하는 것은 아님
    • 해당 참조값을 꺼낸 후 그 값을 Child 타입으로 변환하는 것이라 기존 poly 타입은 Parent로 유지

 

 

캐스팅

  • 업캐스팅: 부모 타입으로 변경
  • 다운캐스팅: 자식 타입으로 변경

 

 

일시적 다운 캐스팅

  • Parent poly = new Child();
  • ((Child) poly).childMethod();
    • 정확히는 Parent poly가 Child 타입으로 바뀌는 것이 아니라 잠깐 바뀜

 

다운 캐스팅 주의점

다운 캐스팅은 잘못하면 심각한 런타임 오류가 발생할 수 있음

  • Parent 인스턴스 생성 후 Child 다운 캐스팅 해도 메모리(인스턴스) 상 자식 타입 인스턴스가 없음

 

 

 

업캐스팅이 안전하고 다운캐스팅은 위험할 수 있음

  • 업캐스팅은 객체 생성 시 상위 부모 타입이 모두 생성되므로 안전하다.
  • 반면 다운캐스팅은 인스턴스에 존재하지 않는 하위 타입으로 캐스팅하는 문제가 발생할 수 있다.

 

 

instanceof

instanceof 키워드는 인스턴스 타입을 확인할 수 있음

  • new Parent() instanceof Parent // true
  • new Child() instanceof Parent // true
    • 이게 중요 ! 참조의 개념으로 생각하기 
  • new Parent() instanceof Child // false

 

Pattern Matching for instanceof

  • (parent instanceof Child child)
  • Java 16부터 가능
  • instanceof 키워드로 인스턴스인지 확인하고 바로 child 다운캐스팅 변수 생성 가능

 

 

 

 

 

 

다형성과 메서드 오버라이딩

  • 다형성을 이루는 또 하나의 중요한 핵심 이론!
  • 오버라이딩 된 메서드가 항상 우선권을 가짐 !! 중요
  • 멤버 변수는 오버라이딩 되지 않는다.
  • 메서드는 오버라이딩 된다.
  • Parent parent = new Child();
    • parent.value는 부모 value
    • parent.method()는 자식 method
      • 오버라이딩된 메서드는 항상 우선권을 가진다 !!!!!!
      • 물론 자식 인스턴스가 있어야 함

 

 

 

 

 

지금까지 다형성을 이루는 핵심 이론인 다형적 참조와 메서드 오버라이딩에 대해 학습함

  • 다형적 참조: 하나의 변수 타입으로 다양한 자식 인스턴스를 참조할 수 있는 기능
  • 메서드 오버라이딩: 기존 기능을 하위 타입에서 새로운 기능으로 재정의
728x90

댓글