타입으로 견고하게 다형성으로 유연하게 ‐ 서브타입에 의한 다형성 - thought-corner/backend-roadmap GitHub Wiki

서브타입에 의한 다형성(Subtype Polymorphism)

  • 정의
    • A는 B다가 참이면 A는 B의 서브타입이다.이다.
  • 타입 시스템
    • B 타입(슈퍼타입)의 자리에 A 타입(서브타입)이 오더라도 타입 검사기에는 문제가 없다.
// Person은 Student의 슈퍼타입
class Person {
  id: number;
  name: string;
  email: string;
}

// Student는 Person의 서브타입
class Student extends Person {
  grade: number;
  gpa: number;
  paid: boolean;
}
public interface Person {
    String email();
}

public record Student(
        long id,
        String name,
        String email,
        int grade,
        double gpa,
        boolean paid
) implements Person {}

// ...

void sendEmail(Person person, String title, String content) {
    String email = person.email();
    // TO BE IMPLEMENTED
}

Student student = new Student(1L, "harry", "[email protected]", 5, 4.0, true);
sendEmail(student, "title", "content");
  • 타입 검사기가 객체 타입의 서브타입 관계를 판단할 때 사용하는 규칙은 다음과 같다.
    • 이름에 의한 서브타입
    • 구조에 의한 서브타입

이름에 의한 서브타입(nominal subtyping)

  • 정의
    • 타입검사기가 클래스 이름과 클래스 사이의 상속 관계만을 고려한다.
    • 클래스 A가 클래스 B를 상속한다면 A는 B의 서브타입이다.
  • 상속
    • 직접 상속과 간접 상속이 존재한다.
    • ex. StudentSchoolObject의 서브타입이면서 Person의 서브타입이다.
class SchoolObject {}
class Person extends SchoolObject {}
class Student extends Person {}

구조에 의한 서브타입(structural subtyping)

  • 정의
    • 클래스 A가 클래스 B에 정의된 필드와 메서드를 모두 정의한다면 A는 B의 서브타입이다.
  • 특징
    • 타입 검사기가 클래스 사이의 상속관계 대신 클래스 구조(필드와 메서드)를 고려해야한다.
    • 이름에 의한 서브타입을 사용하지 못하는 경우 활용한다.
  • 구현
    • 구조를 드러내는 타입을 사용한다.
    • 객체가 가지는 필드와 메서드를 나열한다.
    • 별도의 클래스를 정의하지않고 항상 잘 작동하게 사용 가능하다.