Part20 - generic

uglyduck.dev·2020년 9월 27일
0

예제로 알아보기 👀

목록 보기
20/22
post-thumbnail

Ex01_generic

package com.mywork.ex;
/*
제네릭 (generic)
    1. 클래스나 메소드에서 컴파일할 때 타입체크(type check)를 하는 기능이다.
    2. 미리 객체(인스턴스)의 공통적인 타입을 명시해서 처리하기 때문에
       안정성이 높고, 캐스팅(형변환)을 생략할 수 있다.
    3. 제네릭 클래스와 제네릭 메소드의 구현이 가능하다.
    4. 모든 컬렉션 프레임워크는 제네릭 처리가 되어 있어 제네릭을 반드시 알아야 한다.
    5. 2개 이상의 제네릭 타입 선언이 가능하다.
    6. 주의사항
        1) T obj = new T();     불가능
        2) T[] arr = new T[3];  불가능
        3) T[] arr;             가능
	
class Box<T>{
	
	private T obj;
	
	public void setObj(T obj){
		this.obj = obj;
	}
	public T getObj(){
		return obj;
	}
	
}

// main
Box<String> box = new Box<>();          // 구체화
Box<String> box = new Box<String>();    // 구체화는 referenceType만 허용

// 컴파일 시점
T <- String

class Box{      // 구체화 된 클래스
	
	private String obj;
	
	public void setObj(String obj){
		this.obj = obj;
	}
	public String getObj(){
		return obj;
	}
	
}
*/
// 만능 박스
class Box{
	
	// Field
	private Object obj;

	// Method
	public void setObj(Object obj) {
		this.obj = obj;
	}
	
	public Object getObj() {
		return obj;
	}
	
}

// 물건들
class BallPen{ }
class Pencil{ }

public class Ex01_generic {
	public static void main(String[] args) {
		Box box = new Box();  // 디폴트 생성자가 자동으로 생성된 뒤 호출됌!
		
		box.setObj(new BallPen());
		BallPen myPen = (BallPen)box.getObj();
		System.out.println(myPen);
		
		box.setObj(new Pencil());
		Pencil myPencil = (Pencil)box.getObj();
		System.out.println(myPencil);
	}
}

Ex02_generic

package com.mywork.ex;

// 제네릭 클래스
class Bag <T>{   // T : 자료형
	
	// Field
	private T obj;
	
	// Method
	public void setObj(T obj) {
		this.obj = obj;
	}
	public T getObj() {
		return obj;
	}
}

// 물건들
class Ball{ }
class Pen{ }

public class Ex02_generic {
	public static void main(String[] args) {
		// 아래 두 가지 모두 가능하다.
		// Bag<Ball> bag = new Bag<Ball>();
		Bag<Ball> bag = new Bag<>();
		
		bag.setObj(new Ball());
		Ball ball = bag.getObj();  // generic 자료형을 사용함으로 써 다운캐스팅할 필요가 없음.
		System.out.println(ball);
	}

}

Ex03_generic

package com.mywork.ex;

/*
 * T[] arr; 			가능
 * T[] arr = new T[3];  불가능
 * 
 * T obj = new T();		불가능
 * 
 */

public class Ex03_generic {
	static <T> void printArray(T[] arr) {	// T[] arr -> 배열의 주소 O 배열 선언만!! 가능
		for(int i = 0; i < arr.length; i++) {
			System.out.print(arr[i]);
		}
		System.out.println();
	
	}
	public static void main(String[] args) {
		Integer[] arr = {1, 2, 3, 4, 5};
		printArray(arr);
		
		Double[] arr2 = {1.5, 2.5, 3.5};
		printArray(arr2);
		
		String[] arr3 = {"hello", "sidney"};
		printArray(arr3);
	}
}

Ex04_generic

package com.mywork.ex;

class Room <T1, T2>{
	// Field
	private T1 furniture1;
	private T2 furniture2;
	
	// Method
	@Override
	public String toString() {
		StringBuffer sb = new StringBuffer();
		sb.append("첫 번째 가구 : ").append(furniture1).append("\n");
		sb.append("두 번째 가구 : ").append(furniture2);
		return sb.toString();
	}
	public void setFurniture1(T1 furniture1) {
		this.furniture1 = furniture1;
	}
	public void setFurniture2(T2 furniture2) {
		this.furniture2 = furniture2;
	}
}

// 가구 (Chair, Table)
class Bed{
	@Override
	public String toString() {
		return "침대";
	}
}
class DressTable{
	@Override
	public String toString() {
		return "옷장";
	}
}
class Chair{
	@Override
	public String toString() {
		return "의자";
	}
}
class Table{
	@Override
	public String toString() {
		return "책상";
	}
}

public class Ex04_generic {
	public static void main(String[] args) {
		
		// Room 생성 2개
		Room<Bed, DressTable> mainRoom = new Room<>();
		Room<Chair, Table> studyRoom = new Room<>();
		
		mainRoom.setFurniture1(new Bed());
		mainRoom.setFurniture2(new DressTable());
		
		studyRoom.setFurniture1(new Chair());
		studyRoom.setFurniture2(new Table());
		
		System.out.println(mainRoom);
		System.out.println(studyRoom);
	}
}

Ex05_generic

package com.mywork.ex;
import java.util.Arrays;

class Container<T>{
	// Field
	private T[] items;
	
	// Constructor
	@SuppressWarnings("unchecked")		// 명확하지 않은 타입 체크이지만 더 이상 경고 날리지 마라!
	public Container(int capacity) {
		items = (T[])(new Object[capacity]);
	}

	// Method
	public void add(T item) {
		// 순차적으로 순회하다가 빈 자리가 발견되면 그 자리에 저장하기
		// items 배열에 item 변수 저장하기
		for(int i = 0; i < items.length; i++) {
			if(items[i] == null) {
				items[i] = item;
				break;
			}
		}
	}
	public T[] getItems() {
		return items;
	}
}
class Gun{
	
	// Field
	private String model;

	// Constructor
	public Gun(String model) {
		this.model = model;
	}
	
	// Method
	@Override
	public String toString() {
		return model;
	}
}
public class Ex05_generic {
	public static void main(String[] args) {
		Container<Gun> container = new Container<>(10);	// Constructor
		
		container.add(new Gun("K1"));
		container.add(new Gun("K9"));
		container.add(new Gun("K3"));
		
		System.out.println(Arrays.toString(container.getItems()));
	}
}

Ex06_generic

package com.mywork.ex;

class Basket <T>{
	
	// Field
	private T[] foods;
	
	// Constructor
	@SuppressWarnings("unchecked")
	public Basket(int length) {
		foods = (T[])(new Object[length]);
	}
	
	// Method
	public void add(T food) {
		for(int i = 0; i < foods.length; i++) {
			if(foods[i] == null) {
				foods[i] = food;
				break;
			}
		}
	}
}
// 음식의 부모
class Food { }                  // interface Eatable { }

// 음식
class Apple extends Food{ }     // class Apple implements Eatable{ }
class Banana extends Food{ }    // class Banana implements Eatable{ }
class Bread extends Food{ }     // class Bread implements Eatable{ }

// 비음식
class Computer{ }

public class Ex06_generic {

	public static void main(String[] args) {
		
		Basket<Food> basket = new Basket<>(5); // Basket<Eatable> basket = new Basket<>(5);
		
		
		basket.add(new Apple());
		basket.add(new Banana());
		basket.add(new Bread());
//		basket.add(new Computer()); // 이 부분을 막고 싶다! (실행 불가)
//		Food food = new Computer() 가 불가하기 때문에!
		
		
	}

}
profile
시행착오, 문제해결 그 어디 즈음에.

0개의 댓글