IT 서적/Object

Object Chapter 012 : 다형성

GustavEiffels 2025. 6. 1. 11:01
반응형
Garbage Collection Guide

다형성

많은 형태를 가질 수 있는 능력으로 쉽게 말해, 인터페이스에 대해
다양한 구현을 가질 수 있는 것을 말한다.

다형성도 굳이 나누자면 강제 다형성과 포함다형성으로 나눌 수 있다.


1. 강제 다형성

상속 관계(혹은 인터페이스 구현)를 통해 발생

상위 클래스(혹은 인터페이스)가 선언한 메시지를 하위 클래스에서 재정의(오버라이딩)하여 사용하며
동적 바인딩을 통해 실행 시점에서 실제 타입 메서드가 호출 됨


2. 포함 다형성

타입을 파라미터화해서 다양한 타입의 객체를 처리할 수 있는 다형성
네릭(Generics) 같은 것: `List`, `Map` 을 사용하며
타입 매개변수로 구체적인 타입을 나중에 지정하고 컴파일 시점에 파일 타입이 확장됨

다시 상속에 대해서

앞에서 봤듯이 상속의 목적은 코드 재사용이 아니라 프로그램을 구성하는 개념들을
기반으로 다형성을 가능하게 하는 타입 계층을 구축하기 위한 것이다.

public class Lecture {
    // 강의 평가 로직 (기본)
}

public class GradeLecture extends Lecture {
    // 특정 조건을 만족하는 평가 방식 추가
}

코드 중복이 제거되고, 공통 로직은 부모 클래스에서 사용

하지만, 부모 클래스의 구현에 강하게 결합되고 `Lecture` 클래스의 평가 로직을 수정하면, `GradeLecture`도 영향을 받는다.
그리고 새로운 평가 방식이 생기면 또 다른 하위 클래스를 만들어야 해서, 클래스 계층이 점점 복잡해진다.

Dynamic Binding & UpCasting


동적 바인딩

프로그램 실행 시점에 실제 객체의 메서드를 호출
컴파일 시점에는 어떤 메서드가 호출될지 알 수 없고, 실행 시점에 객체의 실제 타입을 기준으로 결정

Lecture lecture = new GradeLecture();
lecture.evaluate();

`lecture` 변수는 Lecture 타입이지만, 실제로는 `GradeLecture` 객체가 할당됨.

UpCasting

하위 타입 객체를 상위 타입으로 참조
보통 상속(혹은 인터페이스) 계층에서 발생

GradeLecture gradeLecture = new GradeLecture();
Lecture lecture = gradeLecture; // 업캐스팅

`GradeLecture` 타입 객체를 Lecture 타입 변수로 참조.
하위 클래스의 구현을 바꾸더라도, 클라이언트 코드는 바뀌지 않음
유연성과 확장성이 높아진다.

동적 메서드 탐색과 다형성


객체지향 시스템의 메서드 수행 규칙

  1. 해당 객체에 메서드가 존재하는지 확인 있으면 실행 없다면 부모클래스 탐색
  2. 부모 클래스에서 찾으면 실행 없다면 다시 부모 클래스 탐색
  3. 이러한 과정이 반복되어 찾으면 실행 없으면 예외

여기서 볼 수 있듯이 찾지 못하면 부모 클래스에서 메서드를 찾는 것을 볼 수 있다.
여기서 알아두어야 할 것이 자동적 메시지 위임이다.


자동적 메시지 위임

하위 클래스가 부모 클래스에 정의된 메서드를 재사용할 때,
동으로 부모의 메서드에 메시지를 전달해 주는 것으로 덕분에 부모 클래스 기능을
자연스럽게 사용할 수 있다.

class Lecture{
 void.evaluate();
}

class GradeLecture extends Lecture{
 @Overriding
 void.evaluate();
}

Lecture lecture = new GradeLecture(); 
lecture.evaluate();

자동적 메시지 위임과 메서드 수행 규칙에 의해서
@Overriding 된 메서드의 경우 구현 객체인 GradeLecture 가 먼저 수행된다.

Super 에 대해서

self (this) 는 해당 객체에 대한 탐색을 위한 내부 변수이고
super 는 상속 받은 객체 영역을 탐색하기 위해서 사용한다.

public class GradeLecutre extends Lecture{
 @Override
 public Stgring evalute(){
  return super.evaluate()+", "+gradesStatistics();
 }
}

여기서 super.evaluate() 는 부모 클래스의 eveluate 메시지를 전송하는 것이다.

부모 메서드를 호출하는 것이 아닌 메시지를 전송한다는 말은 바로 상속 받은 객체가 아닌
그 보다 더 상위에 있는 조상 클래스의 메서드가 호출 될 수 도 있다.

super 의 의미는 부모 클래스로 부터 메서드를 탐색하는 것에 지나지 않는다.

부모 클래스를 호출한다는 얘기는 부모 클래스에 무조건 찾으려는 메서드가 존재해야하고
존재하지 않으면 예외가 발생한다.

하지만 탐색의 경우 부모 클래스에 존재하지 않으면 그보다 더 상위 클래스에서
메서드 존재여부를 확인하는 과정이 발생한다.

반응형