상세 컨텐츠

본문 제목

[Java] Generic (제네릭) 정리.

Language/JAVA

by Computer_x86_64 2021. 7. 20. 16:54

본문

해당 내용을 읽기 전

자바의 객체지향 프로그래밍(특히 다형성, 상속)을 이해하고, Wrapper클래스, 알면 좋습니다.

해당 내용은 <Java의 정석>, <생활코딩! 자바의 프로그래밍 입문>, <이것이 자바>다 외 책과 여러 자료를 보고 이해한 내용을 기재한 것입니다. 

쉽게 이해하기 위해 비유적 표현이 많을 수 있습니다.

 

박스 공장이 있다. (갑자기 ...?)

공장은 클라이언트 주문한 박스를 만든다.

 

과일가게, 전자제품, 인형 등 많은 클라이언트로부터 주문을 받고 찍어낸다.

박스에 과일과 전자제품, 인형이 섞이면 안된다.

 

한 종류(타입)만 들어와야한 다 .

그렇다면 사람은 눈으로 안에 내용물을 보고 분별하겠지만 컴퓨터라면 ?

 

박스에 라벨링을 해 어떤 내용물이 담겨야 하는지 알려주는 것이다.

Box라는 클래스를 만들고 어떤 타입을 지정해서 담는 것이다.

 

clas Box<T, u> {
	T size ;
    U u ;
    Box(T size, U u){
    	this.size =size;
        this.u = u;
    }
    ...
}
...
Box<Integer, Toy> boxToy = new Box<Integer, Toy>(new Integer(10), new Toy());
boxToy.put(new Integer(10), new Apple()); //에러 발생 사과는 들어올 수 없다.

박스에 들어갈 수 (매개 타입을) 있는 지정해주는 역할을 해주는 것이다. 

Box라는 객체를 새롭게 만들면 어떤 타입도 사용 가능하다. 

Box<Toy> boxToy = new Box<Toy>();
Box<Fruit> boxFruit = new Box<Fruit>();
Box<Apple> boxApple = new Box<Apple>();

이와 같이 유연하게 매개타입을 지정해 줄수 있다.

 

하지만 이렇게 어떤 타입이든 받아들인다면 사람인지라 실수를 할 수 있다.

제한적으로 사용하고 싶어 진다.

 

<이펙티브 자바>에서는 너무 포괄적인 제네릭은 추천하지 않는다.

최대한 제한적으로 사용하기를 권고한다.

 

<T extends Fruit> : Fruit의 자손만 들어올 수 있다. (Fruit > Apple, Grape) 

<T super Apple> : Apple의 조상만 들어올 수 있다. (Object > Fruit > Apple)

<?> , <T> : 제한이 없다.

 

<T extends Fruit & packagable> : Fruit의 자손만 들어오고 packagable 인터페이스를 구현한 클래스만 들어올수 있다.

 

그리고 중요한 게 있다. 제네릭 클래스가 아니더라도 메서드에 제네릭을 사용할 수 있다.

제네릭 클래스라고 하더라도 제네릭 클래스에서 지정한 타입과는 제네릭 메서드의 지정한 타입은 별개다. 
(이것 때문에 엄청... 시간 날렸다....ㅠㅠ) 

 

아래는 내가 이해한 내용 바탕으로 만든 코드이다. 

package test;

import java.util.ArrayList;
import java.util.Iterator;
//박스에 들어갈 클래스
class Fruit<T, S> {
	T sweet ;
	S size;
	Fruit (T t, S s){ 
		this.sweet = sweet;
		this.size = size;
	}
	public String toString() { return "Fruit"; }

}
//Fruit를 상속받은 Apple
class Apple<T, S> extends Fruit<T, S> {

	String color;
	Apple(T t, S s, String color) {
		super(t, s);
		this.color = color;
	}
	public String toString() { return "Apple"; }

}
//Fruit를 상속받은 Grape
class Grape<T, S> extends Fruit<T, S> {
	String color;
	Grape(T t, S s, String color){
		super(t, s);
		this.color = color;
	}
	public String toString() { return "Grape"; }

}

class Toy<T> {
	T size;
	Toy (T t) { this.size = t; }
	public String toString() { return "Toy"; }

}
//Toy를 상속받은 곰(인형임)
class Bears<T> extends Toy<T> {
	Bears(T t){
		super(t);
	}
	public String toString() { return "Bears"; }
}

interface packagable { public boolean Packaging(); }

class Box<T> implements  packagable {
	private final static int MAX_SIZE=9;  //박스의 맥스값 상수
	private boolean status = false;  //상태정보 false면 오픈 / true면 가득차서 박싱된상태
	ArrayList list = new ArrayList();   //박스에 내용물을 담을 리스트 생성.
	Box(){}
	Box(T t){ 
		if(list.size() == MAX_SIZE) {
			System.out.println("Box max...");
		} else {
			list.add(t);
			if(list.size() == MAX_SIZE) {
				System.out.println("Box limit..");
			}
		} 
	}
	@Override
	public boolean Packaging() {
		return status = true;
	}
	public <U> void put(U u) {
		if(list.size() == MAX_SIZE) {
			int i = list.size()+1;
			System.out.println(i+" Box Max...");
		} else { 
			list.add(u);
			if(list.size() == MAX_SIZE){
				int j = list.size()+1;
				System.out.println(j+" Box Limit");
			}
		}
	}
	public boolean Change() {
		return status = !status;
	}
	
	public void print() {
		Iterator i = list.iterator();
		while(i.hasNext()) {
			System.out.println(i.next());
		}
		System.out.println();
	}
	
}

public class GenericsTest2 {
	public static void main(String[] args) {
		
		//박스 안에 들어갈 품목
		Fruit f = new Fruit(new Integer(10), new Double(2.1));
		Apple a = new Apple(new Integer(10), new Double(2.1), "Green");
		Grape g = new Grape(new Integer(10), new Double(2.1), "Red");
		
		Toy t = new Toy(new Integer(10));
		Bears b = new Bears(new Integer(10));
		
		//박스 종류별로
		Box box = new Box();
		Box<Toy> boxt = new Box<Toy>();
		Box<Fruit> boxf = new Box<Fruit>();
		Box<Apple> boxa = new Box<Apple>();
		Box<Grape> boxg = new Box<Grape>();
		
		box.put(f);
		box.put(a);
		box.put(g);
		box.put(t);
		box.put(b);
		box.<Toy>put(f);
		box.<Toy>put(a);
		box.<Toy>put(g);
		box.<Toy>put(t);
		box.<Toy>put(b);
		box.print();
		
//		boxt.<Toy>put(f);
//		boxt.<Toy>put(a);
//		boxt.<Toy>put(g);
		boxt.<Toy>put(t);
		boxt.<Toy>put(b);
		boxt.print();
		
		boxf.<Fruit>put(f);
		boxf.<Fruit>put(a);
		boxf.<Fruit>put(g);
//		boxf.<Fruit>put(t);
//		boxf.<Fruit>put(b);
		boxf.print();
		
//		boxa.<Apple>put(f);
		boxa.<Apple>put(a);
//		boxa.<Apple>put(g);
//		boxa.<Apple>put(t);
//		boxa.<Apple>put(b);
		boxa.print();
		

	}

}

결과값...

10 Box Limit
10 Box Max...
Fruit
Apple
Grape
Toy
Bears
Fruit
Apple
Grape
Toy

Toy
Bears

Fruit
Apple
Grape

Apple

 

틀린 부분 지적 및 다양한 지식 공유는 환영입니다. 

관련글 더보기

댓글 영역