Java/객체지향

[객체지향][제네릭스] - 제한된 제네릭 클래스, 제네릭스의 제약

얄루몬 2022. 2. 16. 20:56

📖본 포스팅은 '자바의 정석 - 남궁성 저자' 님의 책과 유튜브 강의를 보고 작성되었습니다.

https://youtu.be/3nmfoPeOgoA?list=PLW2UjW795-f6xWA2_MUhEVgPauhGl3xIp 


[제한된 제네릭 클래스]

  • extends로 대입할 수 있는 타입을 제한 (상속을 이용한 제한)
package javajungsuk;

import java.util.ArrayList;

class Fruit implements Eatable{
	public String toString() {
		return "Fruit";
	}
}

class Apple extends Fruit {
	public String toString() {
		return "Apple";
	}
}

class Grape extends Fruit {
	public String toString() {
		return "Grape";
	}
}

class Toy{
	public String toString() {
		return "Toy";
	}
}

interface Eatable{}


public class Java12_3 {
	public static void main(String[] args) {
		FruitBox<Fruit> fruitBox = new FruitBox<Fruit>();
		FruitBox<Apple> appleBox = new FruitBox<Apple>();
		FruitBox<Grape> grapeBox = new FruitBox<Grape>();
	//  FruitBox<Grape> grapeBox = new FruitBox<Apple>(); //에러. 타입 불일치
	//  FruitBox<Toy> toyBox = new FruitBox<Toy>(); //에러
		
		fruitBox.add(new Fruit());
		fruitBox.add(new Apple());
		fruitBox.add(new Grape());
		appleBox.add(new Apple());
		//appleBox.add(new Grape()); 에러. Grape는 Apple의 자손이 아님.
		grapeBox.add(new Grape());
		
		System.out.println("fruitBox" + fruitBox);
		System.out.println("appleBox" + appleBox);
		System.out.println("grapeBox" + grapeBox);
		
		
	}
}

class FruitBox<T extends Fruit & Eatable> extends Box<T>{}

class Box<T>{
	ArrayList<T> list = new ArrayList<T>();
	void add(T item) {
		list.add(item);
	}
	T get(int i) {
		return list.get(i);
	}
	int size() {
		return list.size();
	}
	public String toString() {
		return list.toString();
	}
}
[결과값]
fruitBox[Fruit, Apple, Grape]
appleBox[Apple]
grapeBox[Grape]

잘살펴보면 제네릭스와 상속을 이용해서 담을 수 있는 것들을 제한해주고 있다.

 

 

 

[제네릭스의 제약]

  • 타입 변수에 대입은 인스턴스 별로 다르게 가능하다.

 

  • static멤버에 타입 변수 사용 불가하다.
    • 모든 인스턴스에 공통이 static이기 때문에 static 타입 변수에 사용이 불가하다.
    • class Box<T>{
          static T item; //에러
          static int compare(T t1, t2) {...} //에러
          }

 

  • 배열 생성 시 타입 변수 사용 불가하다. 타입 변수로 배열 선언은 가능하다.
    • class Box<T>{
          T[] itemArr; // T타입의 배열을 위한 참조변수
          
          T[] toArray(){
              T[] tmpArr = new T[itemArr.lenght]; //에러 제네릭 배열 생성 불가
              }
          }
    • new 다음에 T오면 안 됨 (객체 생성, 배열생성의 경우)