티스토리 뷰

프로그래밍/Java

자바 ! 제네릭( Generic )

나는연어다 2017. 5. 13. 18:36

제네릭

하나의 코드를 여러 타입에 대하여 재사용하는 기술

C++의 Template 기법과 비슷

구체적인 타입을 사용하지 않고 변수 형태로 적는다.

타입 매개변수: 클래스 타입, 인터페이스 타입, 배열 타입

                등을 나타낼수 있다.


* 보통은 대문자를 이용한다


제네릭을 사용하는 이유? 데이터를 꺼낼 때 마다 타입 변환을 해야하는 

번거로움이 있을 수 있기 때문이다.

(다형성의 Upcasting, Downcasting을 이용한 문제점 보안)




일반 클래스 클래스입니다.

class Student{
     Object name;
    
     void set(Object t){ this.name = t ; }
     Object get() { return name; }
}


일반 클래스에서 제네릭을 이용한 클래스입니다.

class Student<T>{
      T name;
      
      void set(T t) { this.name = t ; }
      T get() { return name; }
}




˚ 제네릭 클래스 사용

- 기초 자료형은 T 대신에 사용할 수 없습니다.

  클래스 객체만 사용할 수 있습니다.



˚ Raw 타입

- 제네릭 클래스의 타입 매개변수가 없는 것 입니다.

ex) Student<String> stu = new String<>();


- 만약 위에서 타입 인수가 생략된다면 Raw타입이 된다.

ex) Student stu = new Student();


※주의할 점은 처음부터 제네릭 클래스가 아니라면 Raw타입으로 사용할 수 없다는 것입니다.



제네릭 메소드


제네릭을 메소드에도 사용할 수 있다.



제네릭 클래스와는 달리 타입 매개변수의 범위가 메소드 내부로 제한된다.



메소드의 수식자와 반환형 사이에 타입 매개변수가 위치되어야 한다.


public class Example{
         public static <T> T get(T a){
                   return a;
         }
} 


메소드 호출 시 컴파일러는 이미 타입 정보를 알고 있기 때문에 실제 타입을

<>안에 적으면 되지만 생략하여도 된다.


String s = Exaple.<String>getA(yoon);   => String s = Example.getA(yoon);




제네릭에 대한 기본적인 공부를 마치고 실습을 통해 공부하도록 하겠습니다.


과일박스안에 Orange와 Apple인 과일이 있습니다.


이러한 과일을 각각의 박스에 담는 것을 일반적인 방식과 제네릭을 사용한 방식으로 실습하겠습니다.




과일박스(Fruit Box) 클래스입니다.

public class FruitBox {
	private Fruit fruit;

	public void putFruit(Fruit fruit) {
		System.out.println(fruit + "을 담습니다.");
		this.fruit = fruit;
	}
	
	public Fruit getFruit(){
		System.out.println(fruit+"을 꺼냅니다.");
		return fruit;
	}
}



Fruit 클래스입니다.

public class Fruit {
	private int sugar;
	private String color;

	public Fruit(int sugar, String color) {
		this.sugar = sugar;
		this.color = color;
	}

	public void showFruitInfo() {
		System.out.println("당도: " + this.sugar + "%");
		System.out.println("색깔: " + this.color + "색");
	}
}



Fruit 클래스를 상속(extends)받은 Orange 클래스입니다.

public class Orange extends Fruit {

	public Orange() {
		super(20, "주황");
	}
	@Override
	public String toString() {
		return "오렌지";
	}
	
	public void goo(){
		System.out.println("Orange.goo()");
	}

}



Fruit class를 상속(extends)받은 Apple 클래스입니다.

public class Apple extends Fruit {

	public Apple() {
		super(10, "빨강");
	}
	@Override
	public String toString() {
		return "사과";
	}
	
	public void foo(){
		System.out.println("Apple.foo()");
	}
}



이제 클래스를 사용할 일반 메인 클래스 입니다.

public class ExampleMain{
	public static void main(String[] args) {

		FruitBox fruitBox = new FruitBox();
		

		fruitBox.putFruit(new Apple()); // UpCasting	
		Orange orange2 = (Orange)fruitBox.getFruit();  // DownCasting의 문제점
		
				
		Apple apple = (Apple) fruitBox.getFruit(); // UpCasting 된 것을 받게되므로
													// DownCasting
		apple.foo();
		System.out.println("꺼낸 과일: " + apple);

		fruitBox.putFruit(new Orange());// UpCasting
		Orange orange = (Orange) fruitBox.getFruit();// UpCasting 된 것을 받게되므로
														// DownCasting
		orange.goo();
		System.out.println("꺼낸 과일: " + orange);

	}
}



일반 메인 클래스와 제네릭을 사용한 메인클래스를

비교하며 공부하겠습니다.



제네릭을 사용한 메인 클래스입니다..

public class ExampleGeneric{
	public static void main(String[] args) {
		FruitBox appleBox = new FruitBox(); // 뒤에 <>에는 비어도 상관없다.
		FruitBox orangeBox = new FruitBox<>();
		
		
		appleBox.putFruit(new Apple());
		orangeBox.putFruit(new Orange());

		// Orange orange = (Orange)appleBox.getClass(); 이미 appleBox로 설정되어있기 때문에
		// 안된다. 
		
		// 객체형태로 데이터베이스로 보낼때 사용하며, 컬렉션 프레임워크에서 중요하다
	}
}


반응형
LIST
댓글
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
TAG
more
«   2024/05   »
1 2 3 4
5 6 7 8 9 10 11
12 13 14 15 16 17 18
19 20 21 22 23 24 25
26 27 28 29 30 31
글 보관함