본문 바로가기
JAVA BASE/GenericsEnumsAnnotation

03. [자바] 제한된 제네릭스 클래스

by staticClass 2021. 1. 8.

T에 지정할 수 있는 타입의 종류를 제한 하는 방법

class Fruit{ ... } // Fruit 클래스
class Apple extends Fruit { ... } Fruit 클래스를 상속받아 만들어진 Apple 클래스
class Grape extends Fruit { ... } Fruit 클래스를 상속받아 만들어진 Grape 클래스
class Toy { ... } // Toy 클래스

class FruitBox<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()               { reutrn list.size(); }
    public String toString() { return list.toString(); }
}

 

특정 클래스와 그 자손들만 타입 매개변수에 대입되게 하기

위와 같은 클래스들이 있다고 가정하고..

FruitBox<Toy> fruitBox = new FruitBox<Toy>();
fruitBox.add(new Toy());   // ok. 과일 박스에 장난감이 들어갔다..

 

extends

위와 같이 과일 박스에 장난감이 들어가게 된다면 문제가 생길 수 있는데 이를 extends를 이용 하여 막을 수 있다.😨

class FruitBox<T extends Fruit> { // Fruit의 자손 타입만 지정가능
    ArrayList<T> list = new ArrayLsit<T>();
    ...
}

한 종류의 타입만 담을수 있다는건 변함 없지만 Fruit의 자손들만 담을 수 있게 제한이 추가됐다.

FruitBox<Apple> appleBox = new FruitBox<Apple>(); // Ok.
FruitBox<Toy> appleBox = new FruitBox<Toy>(); // 에러. Toy는 Fruit의 자손이 아니다.

add()의 매개변수 타입 T도 Fruit와 그 자손 타입이 될 수있기 때문에 여러 과일을 담을 수 있는 상자가 된다.

FruitBox<Fruit> fruitBox = new FruitBox<Fruit>();
fruitBox.add(new Apple());  // OK. Apple이 Fruit의 자손 
fruitBox.add(new Grape());  // OK. Grape이 Fruit의 자손

 

인터페이스를 구현한 클래스만 타입 매개변수에 대입되게 하기

인터페이스를 구현한 클래스만 대입되게 제약도 줄 수 있다.
다만 이때도 Implements를 사용하지 않고 extends를 사용한다.

Interface Eatable {}
class FruitBox<T extends Eatable> { ... }

클래스 Fruit의 자손이면서 Eatable인터페이스도 구현해야만 타입으로 지정 할수 있게 제한 하려면
'&'기호로 연결 해야한다.

class FruitBox<T extends FruitBox & Eatable> { ... }

위와 같은 식으로 표기해주면 Fruit의 자손이면서 Eatable을 구현한 클래스만
타입 매개변수 T에 대입될 수 있다.

댓글