다연이네

[days24] Generics 본문

Java

[days24] Generics

 다연  2020. 10. 23. 22:05
반응형

제네릭

정의: 다양한 타입의 객체들을 다루는 메소드나 컬렉션 클래스에 컴파일 시의 타입 체크를 해주는 기능 

        (compile-time type check)

장점: 객체의 타입을 컴파일시에 체크하기 때문에 객체의 [타입 안정성]을 높이고 [형변환의 번거로움이 줄어든다]. 

        => 코드가 간결해진다.

 

class Box{
	private int value;

	//getter-setter
	public int getValue() {
		return value;
	}
	public void setValue(int value) {
		this.value = value;
	}
	
	//constructor
	public Box(int value) {
		super();
		this.value = value;
	} 

}

위의 코드를 제네릭<T>을 이용해 수정

class Box<T>{
	private T value;

	//getter-setter
	public T getValue() {
		return value;
	}
	public void setValue(T value) {
		this.value = value;
	}
	
	//constructor
	public Box(T value) {
		super();
		this.value = value;
	} 

}

main함수

Box<String> box1 = new Box<>();
box1.setValue("김동준");
Box<Integer> box2 = new Box<>(); 
box2.setValue(123);

package days24;

import java.util.ArrayList;
import java.util.Iterator;

public class Ex02_02 {

	public static void main(String[] args) {
		ArrayList<String>  list = new ArrayList<>();
		list.add("kenik");
		list.add("park");
		list.add("hong");
		// list.add(1);   오류, 데이터의 안정성... 
		
		Iterator<String> ir = list.iterator();
		while (ir.hasNext()) {
			String n = ir.next();  // 형변환 필요 X
			System.out.println( n );
		}
			
		
	}

}

 

제네릭의 제한

class People<T extends Employee>{  }

 -> Employee 클래스의 자식클래스들만 타입 변수(T)로 사용하겠다는 의미 

      == R, S, T 사원들만 사용할 수 있도록 하겠다

  *만일 클래스가 아니라 인터페이스를 구현해야 한다는 제약이 필요한 경우도 implements가 아닌 extends 사용*

 

제네릭 메소드

 static <T> void sort(){ }

- 메서드의 선언부에 제네릭 타입이 선언된 메소드

- 리턴타입 바로 앞에 붙힌다

1. 정렬 타입은 반드시 Comparable을 구현한 인터페이스가 와야한다

(타입 매개변수 줄때는 인터페이스(Comparable)가 올때도 implements 말고 extends 줌)
2. <? super T> : T와 그의 부모만이 올 수 있다는 뜻

 

와일드카드

제네릭 타입이 다른 것만으로는 오버라이딩이 되지 않는다.

  static Juice makeJuice(FruitBox<Fruit> box) {
	String temp = "";
    for(Fruit f : box.getList()) temp+= f+" ";
    return new Juice(temp);
  }
  
  static Juice makeJuice(FruitBox<Apple> box) {
	String temp = "";
    for(Fruit f : box.getList()) temp+= f+" ";
    return new Juice(temp);
  }
  
  //=> 불가능

제네릭 타입은 컴파일러가 컴파일 할때만 사용하고 제거해버린다. 그래서 위의 두 메소드는 오버로딩이 아닌 메소드 중복 정의이다.

이럴때 사용하는 것이 "와일드 카드" 이다. 

<? extends T> : 와일드카드 상한 제한, T와 그 자손들만 가능

<? super T> : 와일드카드 하한 제한, T와 그 조상들만 가능

<?> : 제한없음

static Juice makeJuice(FruitBox<? extends fruit> box) {
	String temp = "";
    for(Fruit f : box.getList()) temp+= f+" ";
    return new Juice(temp);
  }

 

반응형
Comments