본문 바로가기

Java/본격 Java 컬렉션

[Java] 제네릭 클래스 - 과일상자 실습

제네릭(Generic)
 - jdk1.5에서 추가된 문법으로 상당수의 객체에서 사용하고 있는 개념
 - 제네릭을 사용하면 사용하고자 하는 자료형을 클래스에서 미리 지정하지 않고, 인스턴스 생성시 원하는 자료형을 지정할 수 있습니다.

.

.

class Orange{
	int sugar;
	public Orange(int s){ sugar = s; }
	public void showSugar(){ 
		System.out.println("당도 : " + sugar);
	}
}

class FruitBox{
	// 과일 객체를 담는 클래스
	Object item;
	// 과일상자에 담길 과일로서 한 가지가 아닌 여러 가지를 담기 위해 Object로 선언
	public void store(Object item){ this.item = item; }
	public Object pullOut(){ return item; }
}
class FruitBoxObject{
	public static void main(String[] args) {
		FruitBox box1 = new FruitBox();
		box1.store(new Orange(10));
		Orange org1 = (Orange)box1.pullOut();
		// box1.pullOut()으로 받아온 객체를 Orange로 형변환 후 org1에 넣음
		org1.showSugar();

		FruitBox box2 = new FruitBox();
		box1.store(new String("Ornage"));
		// store()메소드의 매개변수가 Object이므로 String객체도 들어감
		Orange org2 = (Orange)box2.pullOut();
		// box2.pullOut()으로 받아온 객체(String 객체)를 Orange로 형변환 할 때 ClassCastException 발생
		org2.showSugar();
	}
} 

/*
문제점 : 에러가 발생하지 않고 예외가 발생하는 것
 - store()메소드의 매개변수로 String객체가 들어가는 것 : 오류 발생 안함
 - 실제 문제가 되는 곳이 아닌 다른 곳에서 예외가 발생

해결책
 - Ornage객체만 들어가도록 작업
*/

.

.

Orange라는 과일 객체를 만들고 그 객체를 담을 수 있는 FruitBox를 만든다. FruitBox에는 어떤 형태의 객체가 올지 올라서 Object로 객체를 담는다고 하자.

그리고 실행하면 컴파일할때는 아무 문제가 안생긴다. 하지만 실행하고 나서는 객체를 담는 과정에서 문제가 생긴다.

Orange라는 객체를 담을 수는 있지만 String 형태로는 예외가 생긴다.

.

.

그러면 첫 번째 해결법으로 Fruit박스에 Orange만 들어갈 수 있도록 코딩해보자

.

.

class Orange{
	int sugar;
	public Orange(int s){ sugar = s; }
	public void showSugar(){ 
		System.out.println("당도 : " + sugar);
	}
}

class OrangeBox{
	Orange item;
	public void store(Orange item){ this.item = item; }
	public Orange pullOut(){ return item; }
}
class FruitBoxOrange{
	public static void main(String[] args) {
		OrangeBox box1 = new OrangeBox();
		box1.store(new Orange(10));
		Orange org1 = box1.pullOut();
		org1.showSugar();

		OrangeBox box2 = new OrangeBox();
		box1.store(new String("Ornage"));
		// 잘못된 객체를 매개변수로 사용하여 에러 발생
		Orange org2 = box2.pullOut();
		org2.showSugar();
	}
}

/*
문제점 : 한 가지 과일 객체만 받을 수 있음
 - FruitBox가 OrangeBox로 바뀜(다른 과일용 클래스도 만들어야 함)

해결책 
 - 모든 종류의 과일객체를 받을 수 있는 Box클래스가 필요
 - 단, 과일객체만을 받게끔 해야 함
*/

.

.

이렇게 하면 Orange객체를 담을 수 있지만 컴파일 하는 과정에서 다른 객체를 담을 때 오류가 생긴다. 그러면 모든 종류에 객체를 받을 수 있으면서 예외나 오류가 안 생기게 할 수 있을까?

그럴 때는 제네릭(Generic)을 사용한다.

.

.

class Orange{
	int sugar;
	public Orange(int s){ sugar = s; }
	public void showSugar(){ 
		System.out.println("당도 : " + sugar);
	}
}

class Apple{
	int weight;
	public Apple(int w){ weight = w; }
	public void showWeight(){
		System.out.println("무게 : " + weight);
	}
}

class FruitBox<T>{
	// FruitBox클래스에서 T라고 지정해 놓은 데이터들은 모두 같은 자료형을 가진다는 의미
	// 단, 무슨 자료형인지는 인스턴스 생성시 지정하게 됨
	// ex) FruitBox<Banana> fr = new FruitBox<Banana>();
	// fr 객체에서 T는 Banana클래스를 의미하는 자료형
	T item;
	public void store(T item){ this.item = item; }
	public T pullOut(){ return item; }
}
class FruitBoxGeneric{
	public static void main(String[] args) {
		FruitBox<Orange> box1 = new FruitBox<Orange>();
		box1.store(new Orange(10));
		Orange org = box1.pullOut();
		org.showSugar();

		FruitBox<Apple> box2 = new FruitBox<Apple>();
		box2.store(new Apple(20));
		Apple app = box2.pullOut();
		app.showWeight();
	}
} 

.

.

클래스명 뒤에 <T>를 선언함으로써 모든 객체를 담을 수 있다.

담는 과정에서 코드 자체에서 변환하여 인스턴스에 담을 수 있다.

728x90
반응형

'Java > 본격 Java 컬렉션' 카테고리의 다른 글

[Java] LinkedList  (0) 2020.07.03
[Java] ArrayList  (0) 2020.07.03
[Java] 컬렉션 프레임워크(Collection Framework)  (0) 2020.07.03
[Java] 제네릭(Generic) 심화  (0) 2020.07.03
[Java] 제네릭 메소드  (0) 2020.07.03