<> 사이에 T,E,K,V 이것은 다 같은 동작을 하고 네이밍은 관습
ex) E는 List, ArrayList 와 같은 컬렉션을 사용할때 사용한다.
T 유형을 의미합니다.
E 엘리먼트 ( List: 엘리먼트 목록)
K 열쇠입니다 (에서 Map<K,V>)
V 값 (반환 값 또는 매핑 된 값)입니다.
하지만 '?'만으로는 Obj와 다를게 없으므로 extents와 super 사용
'<? extends T>' 와일드 카드의 상한제한. T와 그 자손들만 가능
'<? super T>' 와일드 카드의 하한 제한. T와 그 조상들만 가능
'<?>' 제한없음. 모든 타입이 가능 '<? extends Object>'와 동일
지넥릭 클래스와 달리 와일드 카드에서는 '&' 사용 불가능.
예제 12-3
import java.util.ArrayList;
// 클래스 선언부
class Fruit { public String toString() { return "Fruit";}}
class Apple extends Fruit { public String toString() { return "Apple";}}
class Grape extends Fruit { public String toString() { return "Grape";}}
// Juice 클래스
class Juice {
String name;
Juice(String name) { this.name = name = "Juice"; }
public String toString() { return name; }
}
// syso 출력할 주스를 만들어줌 (담겨있는 객체 뽑아냄, 믹서기 안의 과일들)
class Juicer {
static Juice makeJuice(FruitBox<? extends Fruit> box) {
String tmp = "";
for(Fruit f : box.getList())
// 요기가 핵심 부분. box가 Fruit이 아닐 수 있는데, 아니라면 오류가 발생할것임.
// 하지만 하단에 FruitBox의 와일드카드 지네릭클래스 FruitBox를 Fruit으로
// 제한했기 때문에 컴파일러는 위 문장으로부터 모든 FruitBox의 요소들이 Fruit
// 자손이라는 것을 알고 있으므로 문제 삼지 않음.
tmp += f + " ";
return new Juice(tmp);
}
}
// 메인코드 믹서기에 주스를 담고 주스만들기
class FruitBoxEx3 {
public static void main(String[] args){
FruitBox<Fruit> fruitBox = new FruitBox<Fruit>();
FruitBox<Apple> appleBox = new FruitBox<Apple>();
fruitBox.add(new Apple());
fruitBox.add(new Grape());
appleBox.add(new Apple());
appleBox.add(new Apple());
System.out.println(Juicer.makeJuice(fruitBox));
System.out.println(Juicer.makeJuice(appleBox));
} // main
}
// FruitBox가 Fruit과 Fruit을 상속받고있는 그 조상들만 받아들일 수 있도록 약속
class FruitBox<T extends Fruit> extends Box<T> {}
// Box클래스, 믹서기 안에서의 기능
class Box<T> {
ArrayList<T> list = new ArrayList<T>();
void add(T item) { list.add(item); }
T get(int i) { return list.get(i); }
ArrayList<T> getList() { return list; }
int size() { return list.size(); }
public String toString() { return list.toString(); }
}
import java.util.;
// Fruit Vo
class Fruit {
String name;
int weight;
Fruit(String name, int weight){
this.name = name;
this.weight = weight;
}
public String toString() { return name+"("+weight+")";}
}
// Apple 클래스
class Apple extends Fruit {
Apple(String name, int weight){
// 생성자를 통해서 Fruit 부모객체에 name, weight 주입
// 복습
// 2주전? 에 배운것처럼 이런 상황에서 super(); 를 호출 했을때 에러가 날것이다.
// 왜냐하면 Fruit 객체는 기본 생성자 ()가 없기 때문.
super(name, weight);
}
}
class Grape extends Fruit {
Grape(String name, int weight){
super(name, weight);
}
}
// Comparator 인터페이스를 상속, compare 오버라이딩
class AppleComp implements Comparator<Apple> {
public int compare(Apple t1, Apple t2) {
retunr t2.weight - t1.weight;
}
}
class AppleComp implements Comparator<Grape> {
public int compare(Grape t1, Grape t2) {
retunr t2.weight - t1.weight;
}
}
class AppleComp implements Comparator<Fruit> {
public int compare(Fruit t1, Fruit t2) {
retunr t1.weight - t2.weight;
}
}
class FruitBoxEx4 {
public static void main(String[] args) {
FruitBox<Apple> appleBox = new FruitBox<Apple>();
FruitBox<Grape> appleBox = new FruitBox<Grape>();
appleBox.add(new Apple("GreenApple", 300));
appleBox.add(new Apple("GreenApple", 100));
appleBox.add(new Apple("GreenApple", 200));
grapeBox.add(new Grape("GreenApple", 400));
grapeBox.add(new Grape("GreenApple", 300));
grapeBox.add(new Grape("GreenApple", 200));
Collections.sort(appleBox.getList(), new AppleComp());
Collections.sort(grapeBox.getList(), new GrapeComp());
System.out.println(appleBox);
System.out.println(grapeBox + "\n");
Collections.sort(appleBox.getList(), new FruitComp());
Collections.sort(grapeBox.getList(), new FruitComp());
System.out.println(appleBox);
System.out.println(grapeBox);
} // main
}
class FruitBox<T extends Fruit> extends Box<T> {}
ckass Box<T> {
ArrayList<T> list = new ArrayList<T>();
void add(T item) {
list.add(item);
}
T get(int i){
return list.get(i);
}
ArrayList<T> getList() { return list; }
int size() {
return list.size();
}
public String toString() {
return list.toString();
}
}
static <T> void sort(List<T> list, Comparator<? super T> c)
// 선언부의 T와 매개변수의 T는 전혀 다른 별개의 것이다.
앞에 나왔던 makeJuice 메서드를 지네릭 메서드로 바꾸는 예시
static Juice makeJuice(FruitBox<? extends Fruit> box){
}
static <T extends Fruit> Juice makeJuice(FruitBox<T> box){
}