[다형성의 단점]
: 앞에서 알아보았던 다형성(Scheme, Ruby등)은 런타임 검사가 필요한데, 이는 높은 비용과 오류 알림의 딜레이를 유발한다..
: 명시적 파라미터의 다형성( = 일반화)는 프로그래머가 서브루틴이나 클래스를 선언할때 타입 파라미터들을 명시할 수 있게 한다.
=> 컴파일러가 이 파라미터를 서브루틴이나 클래스 선언시에 사용(컴파일 시점 검사)
[Generic의 발전]
: Ada기준. Generic. 즉 일반화는 기존의 다형성 방식은 받는 타입에 따라 같은이름의 메소드를 여러개 생성해야 하지만 이를 템플릿화(일반화) 하고자 하는 아이디어에서 나타났다.
# Ada에서의 일반화
// 기존 다형성 방식 function min(x,y : integer) return integer is ... function min(x,y : long_float) return long_float is ... // 두개가 같은 name이지만 받는 타입에 따라 여러개 메소드 생성
// 일반화 방식 ... function min(x, y : T) return T is ... // 위에서 T를 generic 타입으로 선언 해줌 |
: 그리고 일반화된 메소드 사용시 Ada는 사용할 타입 명시 필요 "min(integer, "<") 하지만 C는 컴파일러가 대신 만드어준다.
# 객체지향 언어에서의 일반화
: Generic은 (C에서는 templete) 전체 클래스를 파라미터화 하기위해 사용되는 가장 일반적인 방식이다. ( <-> Duck typing)
: container형태로 전달되는 클래스들에게 주로 사용된다
: 스택, 큐, 힙, 세트, 사전형(매핑) / 리스트, 배열, tress, 해시테이블 등에서 주로 사용된다.
: 일반화 없으면 앞에서 보았듯이 universal 클래스를 사용해야하는데 이는 type cast 필요하고 컴파일 시점 검사를 못한다.
# 객체지향 언어에서의 일반화 예시
ArrayList<A> a = new ArrayList<A>(); // A나 A의 상속되는 타입만 해당 a 배열에 들어갈수있다. (컴파일 시점) |
# C++에서의 일반화
template<class item, int max_items = 100> // C, C++에서는 templete을 일반화 하는데 사용한다. |
: 여기서 중요한건 JAVA와 C#에서는 오로진 타입들만 일반화 파라미터로써 사용가능하지만,
: Ada와 C++은 값들을 일반화의 파라미터로 사용할 수 있다.
: 단, C++에서 파라미터로 사용되는 값은 컴파일-시점 상수 여야하고, Ada는 동적크기 배열 지원할때, 변수를 사용해도된다(동적시점까지 연기가능)
[실행 옵션Implementation Options)]
: 일반화는 여러가지 방법으로 실행될 수 있다.
# Ada와 C++에서의 일반화 실행
: 순수한 정적 매커니즘
: 모든 작업이 컴파일 시점에 일반화 코드의 다중 인스턴스들이 생성되고 사용되어야 한다.
: 일반적인 케이스에서, 컴파일러는 코드의 모든 인스턴스에 대해 separate copy를 생성한다.
: 같은 종류의 타입을 가지고 있는 클래스는 enqueue와 dequeue 루틴 코드를 공유한다.
class q; q q1; q q2; //에서 q1의 q와 q2의 q는 같은 코드를 공유한다. |
# JAVA에서의 일반화 실행
: 위와 반대로, 일반화에 주어진 모든 인스턴스들이 실행 시점에 같은 코드를 공유한다.
: 기준을 베이스 클래스인 Object로 잡는다.
: 즉, 일반화가 어떤 종류의 파라미터를 받던 간에, 같은 코드를 공유한다.
q<int>, q<process> // 받는 타입 파라미터 달라도 같은 q 코드 공유한다. |
# C#에서의 일반화 실행
: C++ 방식과 JAVA의 방식을 섞은 형태
: C++와 같이, 서로 다른 타입들에 대한 일반화의 특화된 실행을 생성한다.
: JAVA와 같이, 일반화 코드 그 자체가 분명히 안전할 것을 요구한다.
: Object와 같이 위에서 상속 받는 클래스 존재.
# 결론적으로 언어별로 일반화 구현되는 방식이 다르다는 것을 알수 있다.
[일반화 파라미터의 제약]
: 일반화는 추상화인 만큼, 일반화의 인터페이스(선언의 header부분)가 추상적인 사용자가 알고 있어야 하는 것들에 대한 모든 정보를 제공하는것이 중요하다.
# JAVA와 C#에서의 일반화 파라미터의 제약
: 부모클래스 타입이나 인터페이스로부터 일반화를 계승할 수 있는 객체 지향 형식의 능력을 이용하는 제약조건에 대해깨끗한 접근방식을 채택한다.
# JAVA 일반화 파라미터 상속 예시
public static <T extends Comparable<T>> // T는 Comapareble를 상속한 객체 void sort(T A[]) { ... if (A[i].compareTo(A[j]) >= 0 ) // compareTo를 구현한 애들만 T에 들어올 수 있다. ... Integer[] myArray = new Integer[50]; sort(myArray); |
# C# 일반화 파라미터 상속 예시
static void sort<T>(T A[]) where T : Icomparable { // Java처럼 Compareable 상속 의미 .. if (A[i].compareTo(A[j] >= 0) ... int[] myArray = new int[50]; sort(myArray); |
: JAVA와 사용방법 다르지만 비슷하다.
: C# 컴파일러는 int타입이 primitive 타입인걸 충분히 인지할 정도로 똑똑하기에, 정렬에 대한 커스텀된 실행을 제공한다.
: Java의 Integer wrapper class 사용을 제거하게 해준다.
# C++ 일반화 파라미터의 제약
: 몇몇 언어들은 제약 명시를 포기하지만, 여전히 파라미터가 어떻게 사용되는지 검사한다. ex) C++
# C++ 일반화 파라미터 예시(일반화된 정렬 루틴의 header)
template<typename T> void sort(T A[], int A_size) {... |
: 앞과 같이 T중 Comparable 있는 것만 구별할 수 있는 방법이 없다.
: 그래서 그냥 T 타입이면 우선 사용할 순 있는데, 컴파일러가 T중 compareTo 함수 없는 거 사용시 오류를 식별 해준다.
: 그래서 프로그래머가 어느 부분에서 오류 나타날지 예측하기가 어렵다.
: 또한, 특정 케이스에선 원하던 결과와 다른 결과가 나올 수도 있다. ex) int와 double 타입에 대해 <는 메모리내 lower 주소만 참조
: 그래서 프로그래머는 JAVA와 C#을 에뮬레이트 하는데 주로 사용한다.
[암시적 인스턴스화(implicit instantiation)]
: 클래스는 타입이기에, 일반화 클래스(Object)는 사용되기 전에 인스턴스를 생성해줘야 한다.
# 일반화 클래스에 대한 인스턴스 생성
queue<int,50>* myQueue = new Queue<int, 50(); // C++, 여기선 new를 이용해 인스턴스 생성 |
# 몇몇 언어 (Ada등)들은 사용되기 이전에 암시적 인스턴스화 하기위해 일반화 서브루틴을 필요로 한다.
procedure int_sort is new sort(integer, int_array, "<"); |
# C++, JAVA, C#에서의 암시적 인스턴스화
: 위와 같은 작업 필요 없다.
sort(ints, 10); sort(reals, 50); // 아래 와 같이 사용하지 않고 위처럼 사용 가능 int ints[10]; double reals[50]; |
: 그냥 이렇게 쓰면 컴파일러가 알아서 내부적으로 코드를 생성해준다.
[C++, JAVA, C#에서의 일반화]
1. C++에서의 일반화
: C++에서는 일반화가 좀더 다양화 되어 사용된다.
2. JAVA, C#에서의 일반화
: container 생성까지만 일반화 사용하게끔 순수하게만 제공된다.
'[프로그래밍 언어론]' 카테고리의 다른 글
프로그래밍 언어론 7-4강. 균등 테스팅과 할당(Equality Testing and Assignment) (0) | 2019.12.15 |
---|---|
프로그래밍 언어론 7-3강. 파리미터의 다형성 (Parametric Polymorphism) (0) | 2019.12.15 |
프로그래밍 언어론 7-2-3강. 타입 추론(Type Inference) (0) | 2019.12.14 |
프로그래밍 언어론 7-2-2강. 타입 호환성(Type Compatibility) (0) | 2019.12.13 |
프로그래밍 언어론 7-2-1강. 타입 동등성(Type Equivalence) (0) | 2019.12.13 |