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를 합니다.
'JAVA' 카테고리의 다른 글
[Java] 6-1강 - Collection Framework 1 (List - ArrayList, Vector, LinkedList, Stack & Queue) (0) | 2020.12.03 |
---|---|
[Java] 6-0강 - Collection Framework (0) | 2020.12.03 |
[Java] 5-1강 - Generic Programming 1 (generic의 기본) (0) | 2020.11.17 |
[Java] 4-1강 - 예외 처리 (0) | 2020.11.17 |
[Java] 2-3강 - 객체 지향 프로그래밍 3 (Abstraction - Interface) (0) | 2020.10.16 |