Java의 제네릭에 대해서 남은 개념들에 대한 22강이었다.
와일드카드라는 기능에 대한 설명이 길게 진행되었는데, 확실히 쉽게 이해하기는 힘들었다.
지금도 조금씩 헷갈리는 데, 복습을 확실히 해야겠다.
제네릭 클래스의 상속
- 제네릭 클래스 인스턴스와 참조변수간의 관계는 기본적인 상속 관계와 동일하게 작동한다. 단, <> 키워드로 감싸진 타입 매개변수가 동일해야 함
class Box<T> {
protected T ob;
public void set(T o) { ob = o; }
public T get() { return ob; }
}
class PaperBox<T> extends Box<T> {
public PaperBox(T o) {
ob = o;
}
}
Box<Integer> iBox = new PaperBox<Interger>; //참조 가능
Box<String> sBox = new PaperBox<Integer>; //참조 불가능
타겟 타입
- 컴파일러가 참조변수의 매개변수화 타입을 기반으로 후행하는 메소드의 타입 매개변수를 결정하는 것
class Box<T> {
private T ob;
public void set(T o) { ob = o; }
public T get() { return ob; }
}
class EmptyBoxMake {
public static <T> Box<T> makeBox() {
Box<T> obx = new Box<T>;
return box;
}
}
public static void main(String[] args) {
Box<Integer> iBox1 = EmptyBoxMake.<Integer>makeBox(); //일반적인 제네릭 메소드 호출
Box<Integer> iBox2 = EmptyBoxMake.makeBox(); //타겟 타입을 사용해서 제네릭 메소드 호출
iBox.set(25);
System.out.println(iBox.get());
}
와일드카드
- <> 키워드 안에 ?를 사용해서 와일드카드를 사용할 수 있다.
- 와일드카드 기능을 사용하면 어떤 타입도 사용이 가능하다.
- 제네릭을 사용해서 정확하게 동일하게 작동하게 만들수 있지만 와일드카드를 사용하는 방식이 좀 더 권고되는 방식이다.
public static <T> void innerPrint(Product<T> product) {
System.out.println(product);
} //제네릭 기반 메소드 정의
public static void innerPrint(Product<?> product) {
System.out.println(product);
} //와일드카드 기반 메소드 정의
- 와일드카드에는 상한과 하한의 개념이 존재한다.
- 상한 : extends 키워드를 사용해서 제한을 하며, 지정한 클래스부터 해당 클래스를 상속하는 하위 클래스만 사용이 가능하게 제한을 거는 것
- 하한 : super 키워드를 사용해서 제한을 하며, 지정한 클래스부터 해당 클래스가 상속하는 상위 클래스만 사용이 가능하게 제한을 거는 것
public static void peek(Box<? extends Number> box) {
System.out.prinln(box);
} //상한 제한으로 이 메소드에는 Number 클래스를 상속하는 하위 클래스(ex.Interger 등)들만 사용할 수 있다.
public static void peek(Box<? super Interger> box) {
System.our.println(box);
} //하한 제한으로 이 메소드에는 Integer 클래스가 상속하는 상위 클래스(ex. Number, Object 등)들만 사용할 수 있다.
- 상한, 하한의 목적
- 컴파일 오류를 검출하기 위한 목적, 코드의 안정성을 확보할 수 있다.
- 일반적인 get, set 기능중 상한을 설정하면 get이 가능하고, set이 불가능하고 하한을 설정하면 get이 불가능하고, set이 가능하다.
- 상한과 하한의 차이점을 파악하면 메소드의 인자 구성을 통해서 해당 메소드의 기능을 간접적으로 파악하는데에 도움이 됨
- 제네릭 메소드의 경우에도 와일드카드를 사용할 수 있다.
- 제네릭 메소드의 경우, 메소드 오버로딩을 적용할 수 없기 때문에 와일드카드를 적용한 메소드를 사용한다.
제네릭 인터페이스
- 인터페이스의 경우에도, 클래스와 메소드와 동일하게 제네릭으로 정의할 수 있다.
'프로그래밍 > Java' 카테고리의 다른 글
Java - Collection (2) (0) | 2020.10.09 |
---|---|
Java - Collections (1) (0) | 2020.10.09 |
Java - 제네릭 (1) (0) | 2020.09.22 |
Java - Java의 기본 클래스 (2) (0) | 2020.09.21 |
Ubuntu에서 Java 개발환경 세팅 (0) | 2020.09.14 |