반응형
제한된 타입 파라미터 문법
: 구체적인 타입을 제한할 필요가 있어 사용된 문법
ex)
public static <타입글자 extends 제한할타입> 리턴타입 메소드 이름(클래스<타입글자> 파라미터명)
package kr.or.ddit.basic;
class Util2 {
public static <T extends Number> int compare(T t1, T t2) {
double v1 = t1.doubleValue();
double v2 = t2.doubleValue();
// v1이 크면 양수, v1이 작으면 음수 출력
return Double.compare(v1, v2);
}
}
public class T04GenericMethodTest {
public static void main(String[] args) {
int result1 = Util2.compare(10, 20);
System.out.println(result1);
System.out.println();
int result2 = Util2.compare(3.14, 3);
System.out.println(result2);
System.out.println();
// 숫자 타입이 아니기에 오류 발생
// System.out.println(Util2.compare("C", "JAVA"));
}
}
package kr.or.ddit.basic;
import java.util.ArrayList;
import java.util.List;
public class T05WildCardTest {
public static void main(String[] args) {
FruitBox<Fruit> fruitBox = new FruitBox<>(); // 과일상자
FruitBox<Apple> appleBox = new FruitBox<>(); // 사과상자
fruitBox.add(new Apple());
fruitBox.add(new Grape());
appleBox.add(new Apple());
appleBox.add(new Apple());
// appleBox.add(new Grape()); // 사과만 넣을 수 있는데 다른 것을 넣으려고 해서 에러 발생.
}
}
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 + ")";
}
}
class Apple extends Fruit {
public Apple() {
super("사과");
}
}
class Grape extends Fruit {
public Grape() {
super("포도");
}
}
// 과일상자 클래스
class FruitBox<T>{
private List<T> fruitList;
public FruitBox() {
fruitList = new ArrayList<>();
}
public List<T> getFruitList() {
return fruitList;
}
public void add(T fruit) {
fruitList.add(fruit);
}
}
package kr.or.ddit.basic;
import java.util.ArrayList;
import java.util.List;
public class T05WildCardTest {
public static void main(String[] args) {
FruitBox<Fruit> fruitBox = new FruitBox<>(); // 과일상자
FruitBox<Apple> appleBox = new FruitBox<>(); // 사과상자
fruitBox.add(new Apple());
fruitBox.add(new Grape());
appleBox.add(new Apple());
appleBox.add(new Apple());
// appleBox.add(new Grape()); // 사과만 넣을 수 있는데 다른 것을 넣으려고 해서 에러 발생.
Juicer.makeJuice(fruitBox);
// Fruit 타입만 허용하는데, Apple 타입을 넣었기에 에러 발생
// => makeJuice와 그 안에 있는 for 타입을 제너릭으로 변환해야함
Juicer.makeJuice(appleBox);
}
}
class Juicer {
static <T extends Fruit> void makeJuice(FruitBox<T> box) {
// static void makeJuice(FruitBox<Fruit> box) {
String fruitListsStr = ""; // 과일 목록
int cnt = 0;
for (T f : box.getFruitList()) {
if(cnt == 0) {
fruitListsStr += f;
} else {
fruitListsStr += ", " + f;
}
cnt++;
}
System.out.println(fruitListsStr + " => 주스 완성!!!");
}
}
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 + ")";
}
}
class Apple extends Fruit {
public Apple() {
super("사과");
}
}
class Grape extends Fruit {
public Grape() {
super("포도");
}
}
// 과일상자 클래스
class FruitBox<T>{
private List<T> fruitList;
public FruitBox() {
fruitList = new ArrayList<>();
}
public List<T> getFruitList() {
return fruitList;
}
public void add(T fruit) {
fruitList.add(fruit);
}
}
와일드카드 (Wild Card)
: 제너릭 타입을 이용한 타입으로, 변수 선언과 객체 생성 및 메서드를 정의할 때 사용된다.
결정되지 않은 타입을 선언하기 위해 사용.
=> 와일드카드로 인해 무조건 제너릭 타입을 위해 제너릭 메소드를 사용하지 않아도 됨. (일반 메소드 사용 가능)
- 사용 방법
<? extends 타입> => 와일드카드의 상한 제한. T와 그 자손들만 가능
<? super 타입> => 와일드카드의 하한 제한. T와 그 조상들만 가능
<?> => 모든 허용가능한 타입이 가능
ex)
List<?> list = new ArrayList<Integer>();
package kr.or.ddit.basic;
import java.util.ArrayList;
import java.util.List;
public class T05WildCardTest {
/*
* 와일드 카드에 대하여...
*
* 와일드카드(?)는 제너릭 타입을 이용한 타입.
* 안전한 코드를 위해 사용되는 특별한 종류의 인수(Argument)로서,
* 변수 선언, 객체생성 및 메서드를 정의할 때 사용된다.
*
* <? extends T> => 와일드카드의 상한 제한. T와 그 자손들만 가능
* <? super T> => 와일드카드의 하한 제한. T와 그 조상들만 가능
* <?> => 모든 허용가능한 타입이 가능
*/
public static void main(String[] args) {
FruitBox<Fruit> fruitBox = new FruitBox<>(); // 과일상자
FruitBox<Apple> appleBox = new FruitBox<>(); // 사과상자
fruitBox.add(new Apple());
fruitBox.add(new Grape());
appleBox.add(new Apple());
appleBox.add(new Apple());
Juicer.makeJuice(fruitBox);
Juicer.makeJuice(appleBox);
}
}
class Juicer {
static void makeJuice(FruitBox<? extends Fruit> box) { // 일반 메소드
// static <T extends Fruit> void makeJuice(FruitBox<T> box) { // 제너릭 메소드
String fruitListsStr = ""; // 과일 목록
int cnt = 0;
for (Object f : box.getFruitList()) {
if(cnt == 0) {
fruitListsStr += f;
} else {
fruitListsStr += ", " + f;
}
cnt++;
}
System.out.println(fruitListsStr + " => 주스 완성!!!");
}
}
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 + ")";
}
}
class Apple extends Fruit {
public Apple() {
super("사과");
}
}
class Grape extends Fruit {
public Grape() {
super("포도");
}
}
// 과일상자 클래스
class FruitBox<T>{
private List<T> fruitList;
public FruitBox() {
fruitList = new ArrayList<>();
}
public List<T> getFruitList() {
return fruitList;
}
public void add(T fruit) {
fruitList.add(fruit);
}
}
package kr.or.ddit.basic;
import java.util.ArrayList;
import java.util.List;
public class T06WildCardTest {
// 장바구니 항목 조회를 위한 메서드(모든 항목을 담은 장바구니)
public static void displayCartItemInfo(Cart<?> cart) {
System.out.println("= 음식류 장바구니 항목 리스트 =");
for (Object obj : cart.getCartList()) {
System.out.println(obj);
}
System.out.println("------------------------------------");
}
// 장바구니 항목 조회를 위한 메서드(음료나 그 하위 항목을 담은 장바구니)
public static void displayCartItemInfo2(Cart<? extends Drink> cart) {
System.out.println("= 음료나 그 하위 장바구니 항목 리스트 =");
for (Object obj : cart.getCartList()) {
System.out.println(obj);
}
System.out.println("------------------------------------");
}
// 장바구니 항목 조회를 위한 메서드(고기나 그 상위 항목을 담은 장바구니)
public static void displayCartItemInfo3(Cart<? super Meat> cart) {
System.out.println("= 고기나 그 상위 장바구니 항목 리스트 =");
for (Object obj : cart.getCartList()) {
System.out.println(obj);
}
System.out.println("------------------------------------");
}
public static void main(String[] args) {
Cart<Food> foodCart = new Cart<>();
foodCart.addItem(new Meat("돼지고기", 10000));
foodCart.addItem(new Meat("소고기", 20000));
foodCart.addItem(new Juice("오렌지주스", 1500));
foodCart.addItem(new Coffee("아메리카도", 1500));
Cart<Meat> meatCart = new Cart<>();
meatCart.addItem(new Meat("돼지고기", 10000));
meatCart.addItem(new Meat("소고기", 20000));
// meatCart.addItem(new Juice("오렌지주스", 1500)); // 타입 지정으로 인해
// meatCart.addItem(new Coffee("아메리카도", 1500)); // 담을 수 없음
Cart<Drink> drinkCart = new Cart<>();
// drinkCart.addItem(new Meat("돼지고기", 10000)); // 타입 지정으로 인해
// drinkCart.addItem(new Meat("소고기", 20000)); // 담을 수 없음
drinkCart.addItem(new Juice("오렌지주스", 1500));
drinkCart.addItem(new Coffee("아메리카도", 1500));
displayCartItemInfo(foodCart);
displayCartItemInfo(meatCart);
displayCartItemInfo(drinkCart);
System.out.println("\n\n========================================================");
// 음료나 그 하위 항목
// displayCartItemInfo2(foodCart);
// displayCartItemInfo2(meatCart);
displayCartItemInfo2(drinkCart);
System.out.println("\n\n========================================================");
// 고기나 그 상위 항목
displayCartItemInfo3(foodCart);
displayCartItemInfo3(meatCart);
// displayCartItemInfo3(drinkCart);
}
}
class Food {
private String name;
private int price;
public Food(String name, int price) {
super();
this.name = name;
this.price = price;
}
@Override
public String toString() {
return this.name + "(" + this.price + "원)";
}
}
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);
}
}
/**
* 장바구니 클래스
* @param <T>
*/
class Cart<T> {
private List<T> cartList;
public Cart() {
cartList = new ArrayList<>();
}
public List<T> getCartList() {
return cartList;
}
public void addItem(T item) {
cartList.add(item);
}
}
반응형
'자바' 카테고리의 다른 글
[Java 고급] 7.5장 Test (0) | 2024.01.27 |
---|---|
[Java 고급] 7장 enum (1) | 2024.01.27 |
[Java 고급] 5장 가변형 인수, Generics 클래스&메소드 (1) | 2024.01.27 |
[Java 고급] 4장 Properties (0) | 2024.01.27 |
[Java 고급] 3.5.2장 Test2 (1) | 2024.01.27 |