본문 바로가기

JAVA

[Java] 5-2강 - Generic Programming 2 (generic 기법 응용)

2. generic 내부의 type들을 자유롭게 응용

1) Limiting Types

특정 class만 generic class의 parameterized type으로 받게 하는 방법

1> 특정 class의 subclass만 받는 방법

2> 특정 interface를 implement한 class만 받는 방법

extend를 사용한다. (implement를 쓰지 않습니다.)

3> 1>과 2>를 동시에 쓰고 싶은 경우

 

2) Generic class의 상속

1> non-generic → generic

2> type parameter가 같으면, generic → generic 상속 가능

3> 부모 generic class는 자식 generic class의 type을 limit하는 것이 가능하다.

부모 generic class의 type variable ⊃ 자식 generic class의 type variable

4> 부모 generic class가 type을 limit 당하면, 자식 generic class도 type에 limit이 있어야 한다.

(limit을 안하면 자식 class의 type이 커져서 문제가 됩니다.)

 

※ 3>과 4>의 원칙부모 generic class의 type이 자식 generic class의 type보다크거나 같아야 한다.

 

cf> for loop 활용법

iterable일 경우 가능합니다. (array, ArrayList 등)

numbers가 array(iterable)이기 때문에 위 문법을 사용할 수 있습니다.

 

 

3) Wild Card

0> raw type이 같지만 parameterized type이 다른 경우

[1] raw type이 같아도 parameterized type이 다르면 상속관계가 아닙니다.

- 그래서 FruitBox<Fruit>에서 정의된 method를 FruitBox<Apple>에서 쓸 수 없습니다.

[2] raw type이 같아서 본질적으로 같은 class입니다.

- method overloading(같은 class 내에, method 이름이 같지만 parameter type이 다른 경우)이 불가능

 

※ raw type이 같지만 parameterized type이 다른 경우에도 같은 method를 사용하게 할 수 있는 방법

=> Wild Card

=> ?를 사용합니다.

 

1> <? extends T>

(T이하 class 사용)

parameterized type으로 T 혹은 T를 상속받은 것을 사용해야한다.

 

2> <? super T>

(T이상 사용)

parameterize type으로 T 혹은 T의 super class를 사용해야한다.

 

3> <?>

parameterize type으로 모든 type이 가능합니다.

(<? extend Object> 와 유사하다고 보면 됩니다.)

 

 

 

 

4) generic method

class가 generic한 것과 독립적으로 method만 generic하게 만들 수 있습니다.

1> generic method 정의

return type 앞에 'type variable'에 대한 조건을 제시합니다.

2> generic method 사용

method 앞에 조건에 맞는'parameterized type'을 적어주면 됩니다.

만약 compiler가 parameterize type을 이미 알 수 있는 상황이라면

(parameter가 appleBox의 type이 FruitBox<Apple>이고 fruitBox의 type이 FruitBox<Fruit>이다)

따로 parameterized type에 대해 명시하지 않아도 됩니다.

 

5) Casting Generic Types

cf> 일반 class의 casting rule

[1] upcasting (implicit하게 변환된다.)

Superclass a = new Subclass();

[2] downcasting (explicit하게 변환되며 이를 명시해야합니다.)

Subclass b = new Superclass();

Subclass b = (Subclass) new Superclass();

 

0> generic class에서는 raw type이 같더라도 parameterized type이 다르면 casting이 불가능하다.

(이런 문제는 wild card를 사용해서 해결할 수 있다.)

 

1> wild card의 사용

[1] 사용할 class를 정의

[2] wild card로 할당

(parameterized type은 Fruit 혹은 Fruit의 subclass가 가능하게 설정)

2> explicit type casting

컴파일 error가 일어나지 않으나 warning message 정도만 띄웁니다.

(사람이 직접 확인해야만 합니다.)

 

[1] 이와 같은 코드를 만들었다면

appleBox의 type이 FruitBox<Apple>임을 사용자가 확인하고 써야 합니다.

[2] 아래와 같은 message는 기본적으로 뜹니다.

 

6) Erasure of Generic Type

Type Parameter는 complier가 compile할 때만 존재하고 complie 완료 후에는 없어집니다. 

1> complier는 type variable을 제거하고 특정 class로 변환합니다.

=> 그래서 complie이 완료된 object file에는 generic type이 없습니다.

2> (generic type을 제거한 뒤에는) type cast(type 명시)가 필요한 곳에 type cast를 합니다.