CS

[프로그래밍 언어론] 객체지향과 다형성

Grace 2023. 12. 5. 22:30

추상 자료형

프로그래밍 언어의 추상화

  • 추상화(abstraction)
    • 복잡한 대상을 간략하게 나타내는 것
    • 추상화 방법
      • 추리기: 대상의 관심 있는 부분만 추려서 나타냄
      • 삭제하기: 특별히 관심 없는 부분은 삭제하여 나타냄
    • 프로그래밍 언어의 추상화 종료
      • 제어 추상화(control abstraction): 복잡한 제어 과정을 단순하게 제공
      • 자료 추상화(data abstraction): 복잡한 자료 구조를 단순하게 제공
  • 프로그래밍 언어의 추상화
    • 프로그래밍 언어의 추상화 지원
      • 제어 추상화: 제어 구조, 서브프로그램으로 지원 → 어떻게 수행되는지는 숨기고 무엇이 수행되는지 나타냄
      • 자료 추상화: 자료 구조, 추상 자료형으로 지원 → 자료 표현과 더불어 관련된 연산을 묶어서 나타냄
    • 프로그래밍 언어의 추상화 발전
      • 초기 프로그래밍 언어는 제어 추상화를 추구
      • 자료 구조와 더불어 연산을 묶는 방법이 제시됨에 따라 자료 추상화 개념이 등장하였으며 추상 자료형으로 발전

캡슐화 및 정보 은닉

  • 캡슐화(encapsulation): 여러 대상을 하나의 단위로 묶을 수 있는 기능
  • 정보 은닉(information hiding): 구현 세부 사항을 숨기고 인터페이스만 제공하는 기능
  • 캡슐화와 정보 은닉의 관계
    • 캡슐화와 정보 은닉은 같은 의미로 사용되기도 함
    • 엄밀하게는 약간 다른 개념
      • 캡슐화: 여러 요소를 하나로 묶는 기능
      • 정보 은닉: 외부에 공개하지 않는 원칙

추상 자료형

  • 추상자료형(ADT: Abstract Data Type)
    • 자료 집합과 적용 가능한 연산을 함께 선언한 자료형
    • 자료가 어떻게 구성되는지, 연산이 어떻게 구현되는지 세부 사항은 숨김
    • 연산을 수행하려면 어떻게 해야 하는지 사용법(interface)만 기술
  • 추상 자료형의 장점
    • 수정 용이성: 자료형 사용 부분을 바꾸지 않고 구현 코드를 바꿀 수 있음
    • 재사용성: 여러 다른 상황에서 같은 코드를 재사용할 수 있음
    • 보안성: 구현 세부 사항을 프로그램의 다른 곳에서 바꾸지 못하도록 보호함
  • 자료 표현이 없는 추상 자료형
    • 구체적인 자료 구조를 가정하지 않고 자료형을 생각할 수 있음
    • 극단적으로 연산만으로 자료형을 나타낼 수 있음
    • 자료 표현이 없는 추상 자료형의 경우, 자료형 연산 사이에 만족해야 하는 법칙이 있는 경우가 많음

대수적 자료형(algebraic data type)

타입 자체에 적용 가능한 연산을 통해 만든 새로운 타입

  • 타입 자체에 대한 연산을 정의
  • 이 연산을 하나 이상의 타입에 적용함으로써 만든 새로운 자료형
  • 데카크트 곱: 데카르트 곱을 둘 이상의 자료형에 적용하면 튜플 자료형을 얻을 수 있음

객체와 클래스

  • 객체 지향 개념의 발전
    • 시뮬레이션
      • 초기 객체지향 언어는 시뮬레이션 분야에서 발전함
      • 시뮬레이션을 위해서는 실제 세계에 존재하는 대상을 추상화해야 함
      • 이 대상은 어떤 상태를 가지고 있으며 주위 요구에 반응해야 함
    • GUI(Graphical User Interface)
      • 초기 GUI는 책상을 모형화하였음
      • 책상 위에 새로운 책을 펼치고 이를 넘기거나 공책을 열고 기록하는 등의 작업을 화면 위에 나타내고자 하였음
      • 책, 공책 등을 윈도에 대응시켰으며 넘기거나 기록하는 등의 작업은 이벤트로 나타냄

객체와 클래스

  • 객체
    • 특정 상태를 유지하고 있으며 외부 접근에 반응하는 대상
    • 필요에 따라 상태가 바뀔 수 있음
  • 클래스
    • 객체를 생성하는 기본이 되는 틀
    • 인스턴스: 어떤 클래스를 통해 생성된 객체
  • 메타 클래스: 클래스를 인스턴스로 하는 객체
  • 타입과 클래스
    • 객체지향 언어의 타입 지원: 객체지향 언어는 정적 타입을 지원할 수도 있고 그렇지 않을 수도 있음
    • 정적 타입 객체지향 언어: 클래스 = 타입
      • 정적 타입을 지원하는 언어의 경우 클래스를 타입으로 취급
      • 이 경우 객체는 해당 타입의 원소가 되며 같은 필드와 메소드로 구성
      • 통상 필드는 변수로 구현하며, 메소드는 함수로 구현
    • 동적 타입 객체지향 언어: 객체가 지원하는 메소드에 따라서 타입이 결정되는 타입 시스템
  • 생성자
    • 객체를 생성하는 데 사용되는 특별한 메소드
    • 직접 호출하지 않고 new 연산자나 다른 방법에 의해 자동으로 호출됨
    • 생성자는 통상 중복정의가 가능함
  • 소멸자
    • 객체를 소멸하는 데 사용되는 특별한 메소드
    • 직접 호출하지 않고 delete 연산자나 영역 탈출 등에 의해 자동으로 호출됨
    • 소멸자는 중복정의되지 않음
    • 소멸자를 직접 지원하지 않는 경우에는 garbage collector가 무효 객체를 수거함

객체지향 언어 구현 방법

  • 객체지향의 핵심
    • 객체와 연관된 메소드를 객체에 따라 호출할 수 있다는 것
    • 이를 위해서는 메소드 바인딩이 최대한 늦춰져야 함(늦은 바인딩)
  • 늦은 바인딩의 구현
    • 객체지향의 늦은 바인딩을 구현하기 위해서 통상 VTab(가상함수 테이블)을 이용함
    • 각 객체마다 가상함수 테이블을 정의하고 메소드 호출이 있을 때, 가상함수 테이블에 정의된 메소드를 호출하는 방식으로 늦은 바인딩 구현
  • 늦은 바인딩은 다형성을 구현하는 한 가지 방법

다형성

  • 여러 타입의 데이터를 같은 이름으로 처리할 수 있는 특성
  • 함수 수준에서도, 자료형 수준에서도 활용할 수 있음

다형성 종류

  • 다형성 지원 수준에 따른 다형성 종류
    • 다형 서브프로그램: 여러 타입을 다룰 수 있는 서브프로그램
    • 다형 타입: 타입을 인수로 받는 타입
  • 서브프로그램의 다형성 종류
    • 경험적 다형성
    • 매개변수적 다형성
    • 서브타입 다형성(순수 다형성)

경험적 다형성

  • 실제 구현은 다르지만 의미상 같은 개념의 서브프로그램에 같은 이름을 붙인 형태의 다형성
  • 서브프로그램 이름의 중복정의(overloading): 동일한 참조 환경 내에서 다른 서브프로그램과 이름이 같은 서브프로그램
  • 연산자 중복정의(overloading): 피연산자의 타입에 따라 구현이 달라지는 연산자
  • 중복정의와 기본 인수는 충돌될 수 있음
    • 중복정의의 경우 인수 개수와 타입을 통해 호출 함수를 결정함
    • 인수 기본값이 주어졌을 때 호출 함수를 결정하는 방식과 충돌될 수 있음
    • 이런 경우에 시그니처 매칭 알고리즘 수행 중 오류가 발생함 → 시그니처 매칭 알고리즘: 중복 정의된 함수나 연산자의 실제 구현을 결정할 때 사용되는 알고리즘

매개변수적 다형성

타입을 매개변수로 전달하는 형태의 다형성: 타입 인수는 명시적으로 전달할 수도 있지만 암시적으로 전달될 수도 있음

순수 다형성(서브타입 다형성)

  • IS-A 관계로 대변되는 클래스 상속 관계에 의해 지원되는 다형성
  • 적합 상속: IS-A 의미를 만족하는 상속
  • 상속 관계는 클래스 사이 뿐 아니라 인터페이스 사이에도 성립함
  • 추상 클래스: 극도로 추상화되어 직접 객체를 생성할 수 없는 클래스 → 상속 계층의 상위에 존재하며 다형성을 지원하는 기능을 함
  • 구상 클래스: 직접 객체를 생성할 수 있는 클래스
  • 하위 구상 클래스의 인스턴스는 추상 클래스의 객체로 간주할 수 있으므로 “추상 클래스의 객체를 생성할 수 없다”고 단정할 수는 없음
  • 다중 상속
    • 단일 상속: 순수 다형성을 지원하기 위해서는 통상 한 클래스로부터 상속받으면 됨
    • 다중 상속
      • 어떤 경우에는 IS-A 관계가 여러 부모 클래스에 대해 정의되기도 함
      • 이 경우 다이아몬드 상속 문제가 발생하기도 함
    • 다이아몬드 상속 문제
      • 서브클래스에서 필드마 메소드를 호출할 때, 필드나 메소드 참조가 모호해지는 문제
      • 다중 상속을 허용할 경우에는 어떤 슈퍼클래스의 필드나 메소드가 여러 경로를 통해 중복하여 상속될 수 있으므로 필드나 메소드 참조가 모호해질 수 있음

인터페이스

  • 추상 메소드의 집합으로만 구성된 타입
  • 구체적인 메소드 구현은 구상 클래스에 의해 구현되어야 함
  • 인터페이스는 추상 클래스와 유사한 개념이나 차이 존재
    • 추상 클래스는 클래스 계층에 활용
    • 인터페이스는 클래스 계층과 독립적으로 존재할 수 있음

트레잇(trait)

  • 인터페이스와 매우 유사
  • 일부 메소드는 구현되어 있을 수 있음
  • 트레잇은 상속된다거나 구현한다고 하지 않고 사용(use)한다고 함