quilt code

[고급자바] 와일드 카드 본문

daily/고급자바

[고급자바] 와일드 카드

김뱅쇼 2023. 2. 3. 18:23

와일드카드

와일드카드(?)는 제너릭 타입을 이용한 타입 안전한 코드를 위해 사용되는 특별한 종류의 인수 (Argument)로서,
변수선언, 객체생성 및 메소드를 정의할 때 사용된다.

<? extends T>  : 와일드카드의 상한 제한. T와 그 자손들만 가능. (T는 임의의 타입 글자)
<?    super T>   :  와일드카드의 하한 제한. T와 그 조상들만 가능.
<?>                   :  모든 타입이 가능 <? extends Object> 의미와 동일함

 

 

 1. 과일 예제

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
    public static void main(String[] args) {
        FruitBox<Fruit> fruitBox = new FruitBox<>();  // 과일상자  (<?>와일드 카드 사용시 에러남 => 객체 생성할때는 와일드 카드 사용하면 안됨)
        FruitBox<Apple> appleBox = new FruitBox<>();  // 사과상자
        FruitBox<Garbage> garbageBox = new FruitBox<>();  // 쓰레기상자 (타입 제한이 걸림)
        
        fruitBox.add(new Apple());
        fruitBox.add(new Grape());
        
        appleBox.add(new Apple());
        appleBox.add(new Apple());
        
        garbageBox.add(new Garbage());
        
        Juicer.makeJuice(fruitBox);        
        Juicer.makeJuice(appleBox);        
        //Juicer.makeJuice(garbageBox);        
        
    }
cs

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
class Juicer {
    //static <T extends Fruit> void makeJuice(FruitBox<T> box) {   제너릭 메소드
        static void makeJuice(FruitBox<?> box) {    //일반메소드
        
        String fruitListStr = "";  // 과일목록
        
        int cnt = 0;
        for(Object f : box.getFruitList()) {
            if(cnt == 0) {
                fruitListStr += f;
            } else {
                fruitListStr += "," + f;
            }
            cnt++;
        }
        
        System.out.println(fruitListStr + "=> 쥬스 완성!");
    }
}
cs

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
class Fruit {
    private String name;  // 과일이름
 
    public Fruit(String name) {
        super();
        this.name = name;
    }
 
    public String getName() {
        return name;
    }
 
    public void setName(String name) {
        this.name = name;
    }
    
    @Override
    public String toString() {
        return "과일(" + name + ")";
    }
}
cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
class Apple extends Fruit {
 
    public Apple() {
        super("사과");
    }
        
}
 
class Grape extends Fruit {
    
    public Grape() {
        super("포도");
    }
}
 
class Garbage {
    public String toString() {
        return "음식물쓰레기";
    }
}
cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
class FruitBox<T> {  // <T extends Fruit> : fruit만 들어오라고 타입 제한 
    
    private List<T> fruitList;
    
    public FruitBox() {
        fruitList = new ArrayList<>();
    }
    
    public void add(T fruit) {
        fruitList.add(fruit);
    }
 
    public List<T> getFruitList() {
        return fruitList;
    }
cs

 

 

2. 장바구니 예제

 

1) 장바구니 항목조회를 위한 메소드 (모든 항목)

1
2
3
4
5
6
7
    public static void displayCartItemInfo(Cart<?> cart) {
        System.out.println(" = 음식류 장바구니 항목 리스트 = ");
        for(Object obj : cart.getList()) {
            System.out.println(obj.toString());
        }
        System.out.println("-------------------------");
    }
cs

 

2) 장바구니 항목조회를 위한 메소드 (음료나 그 하위 항목)

 

1
2
3
4
5
6
7
    public static void displayCartItemInfo2(Cart<extends Drink> cart) {
        System.out.println(" = 음료류 장바구니 항목 리스트 = ");
        for(Object obj : cart.getList()) {
            System.out.println(obj.toString());
        }
        System.out.println("-------------------------");
    }
cs

 

3) 장바구니 항목조회를 위한 메소드 (고기류나 그 상위 항목)

1
2
3
4
5
6
7
    public static void displayCartItemInfo3(Cart<super Meat> cart) {
        System.out.println(" =고기류 또는 상위 장바구니 항목 리스트 = ");
        for(Object obj : cart.getList()) {
            System.out.println(obj.toString());
        }
        System.out.println("-------------------------");
    }
cs

 

4) 메인메소드

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
    public static void main(String[] args) {
        
        Cart<Food> foodCart = new Cart<>();
        
        foodCart.add(new Meat("돼지고기"5000));
        foodCart.add(new Meat("소고기"50000));
        foodCart.add(new Juice("토마토쥬스"1200));
        foodCart.add(new Coffee("바닐라딜라이트"5000));
        
        Cart<Meat> meatCart = new Cart<>();
        meatCart.add(new Meat("돼지고기"5000));
        meatCart.add(new Meat("소고기"50000));
        
        Cart<Drink> drinkCart = new Cart<>();
        drinkCart.add(new Juice("토마토쥬스"1200));
        drinkCart.add(new Coffee("바닐라딜라이트"5000));
        
        displayCartItemInfo(foodCart);
        displayCartItemInfo(meatCart);
        displayCartItemInfo(drinkCart);
        
        //displayCartItemInfo2(foodCart);
        //displayCartItemInfo2(meatCart);   info2는 drink만 가능하다고 했기 때문에 에러 발생
        displayCartItemInfo2(drinkCart);
        
        displayCartItemInfo3(foodCart);
        displayCartItemInfo3(meatCart);
        //displayCartItemInfo3(drinkCart); info3는 고기류와 그 상위 항목만 가능하다고 했기 때문에 에러 발생
        
    }
cs

 

5)

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
class Food {
    private String name;   // 음식이름
    private int price;     // 음식가격
    
    public Food(String name, int price) {
        super();
        this.name = name;
        this.price = price;
    }
    public String getName() {
        return name;
    }
    
    @Override
    public String toString() {
        return this.name + "(" + this.price +")";
    }
    
}
 
cs

 

6) 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
class Meat extends Food {
    public Meat(String name, int price) {
        super(name, price);
    }
}
 
class Drink extends Food {
    public Drink(String name, int price) {
        super(name, price);
    }
}
 
class Juice extends Drink {
    public Juice(String name, int price) {
        super(name, price);
    }
}
 
class Coffee extends Drink {
    public Coffee(String name, int price) {
        super(name, price);
    }
}
 
cs

 

7) 장바구니

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
class Cart<T> {
    private List<T> list;
    
    public Cart() {
        list = new ArrayList<>();
    }
 
    public List<T> getList() {
        return list;
    }
    
    public void add(T item) {
        list.add(item);
    }
    
}
cs

'daily > 고급자바' 카테고리의 다른 글

[고급자바] 로또 과제  (0) 2023.02.03
[고급자바] Enum  (0) 2023.02.03
[고급자바] 제너릭 (2)  (0) 2023.02.03
[고급자바] 제너릭 (1)  (0) 2023.02.02
[고급자바] 컬렉션 프레임워크(4)  (0) 2023.02.02