/*
<제네릭>
◎ 제넥릭(Generic)은 어떠한 타입 A가 다른 타입 B에 대한 멤버(변수, 메서드의 반환타입, 매개변수타입 등) 를 가지고
이 타입 B가 동적으로 변하여 A 타입을 다분화하지 않고 능동적으로 사용하기 위해 존재한다.
◎ 단, 제네릭 타입은 기초타입일 수 없음에 유의한다.
public class MonsterBall<T extends Mob>{
private T monster;
public T getMonster() {
return this.monster;
}
public void setMonster(T monster){
this.monster = monster;
}
}
- 위 클래스 MonsterBall 은 T를 제네릭으로 가지는 클래스이고, 이때 T는 Mob 클래스(혹은 인터페이스)를 상속 받음을
강제한다.
- 위 클래스에서 T는 가상의 타입이고 명명법은 T[파스칼 케이스] 로 하는 편이다.(가령, TKey, TValue 등)
- 특정 제네릭에 대한 클래스는 타입으로 사용할 수 있음으로 아래 처럼 변수의 타입으로 사용될 수 있다.
MonsterBall<Wyvern> wmb = new MonsterBall<Wyvern>();
-위 객체화 연산에서 객체를 넘겨받는 타입의 제네릭과 객체화 할 때의 제네릭이 같다면 객체화시의 제네릭 타입은 아래와 같이
생략 가능하다.
MonsterBall<Wyvern> wmb = new MonsterBall<>();
<다이나믹 제네릭(Dynamic Generic)>
◎ 제네릭의 선언부가 아닌 곳에서(클래스 이름 뒤 말고) ? 특수문자를 활용하여 그 타입이 정확히 정해지지 않은 타입에
대한 제네릭을 활용할 수 있다.
MonsterBall<Wyvern> wmb = new MonsterBall<>();
MonsterBall<? extends Mon> someMb = wmb;
위 코드에서 변수 someMb 는 그 타입이 정확히 지정되지 않았지만 Mob 클래스를 상속 받는 (? extends Mob) 제네릭 타입에
대한 MonsterBall 타입임으로 MonsterBall<Wyvern> 타입인 변수 wmb 를 받을 수 있다.
<멀티 타입 파라미터 제네릭(Multi-type Parameter Generic)>
◎ 멀티 타입 파리미터 제네릭 은 어떠한 타입이 제네릭을 두개 이상 가지는 것을 의미하며, 주로 HashMap 혹은 튜플 구현에 사용한다.
◎ 튜플은 서로 다른 두 타입의 값을 쌍(Pair)으로 가지기 위한 타입이다.
-3개 타입에 대한 값을 가지는 타입을 3-튜플(3-Tuple 혹은 Triple 혹은 Triplet 이라 한다.) 그 이상은 잘 안쓰는데
궁금하면 검색.
<부가적인 이야기>
◎ 부모 타입의 변수가 자식 객체를 받을 수 있는것을 다형성의 일환으로 보는 것 처름 원형이 부모 타입인 아형이 원형이 자식타입인
아형의 부모처럼 작동하는 것을 `공변성(Covariant)`이라고 한다. 가령, Object[] 은 String[] 의 부모 타입으로 인식되고 이를
'공변성을 가진다' 라고 한다. 하지만, 제네릭은 공변성을 가지지 않음으로 List<Object> 를 List<String>의 부모라고 하지 않는다
◎ 단, 자바 컴파일의 트릭으로, 제네릭이 공변성을 가지는 것 처럼 작동할 수 있게 하는데, 이가 다이나믹 제네릭의 상속이다.
가령, List<? extends Object> 가 List<String> 의 부모인냥 작동할 수 있게 하는 것이다.
◎ 반대로, List<? super String> 의 꼴에서 이가 가지는 인자는 [String 이 상속 받고 있는 아무 타입]으로, 위 extends 와 반대의
의미이고 이를 `반공변성(Contravariant)`라고 한다.
◎ 궁금하면 https://asuraiv.tistory.com/16 사이트 접속
*/