1. 제네릭 클래스와 상속
2. 타겟 타입
3. 제네릭 메소드 vs 일반 메소드
제네릭 클래스도 상속이 가능하다. 그러나 T에 전달되는 클래스가 동일해야 제대로된 상속 관계로 인정한다.
예시)
GoldBox< Intger> -> Box< Integer> ( ⭕️ )
GoldBox< Intger> -> Box< String> ( ❌ )
class Box<T> {
protected T ob;
public void set(T o) { ob = o; }
public T get() { return ob; }
}
class GoldBox<T> extends Box<T> {
public GoldBox(T o) {
ob = o;
}
}
class GenericInheritance {
public static void main(String[] args) {
Box<Integer> iBox = new GoldBox<>(7959);
Box<String> sBox = new GoldBox<>("Simple");
System.out.println(iBox.get());
System.out.println(sBox.get());
}
}
제네릭 클래스의 상속도 기존 클래스의 상속과 동일하다.
조금 다른 점이라고 하자면 실제로 인스턴스를 생성할 때는 T에 클래스를 넣어 생성하게 되고, T에 들어가는 클래스에 따라 상속에 따른 참조(부모 참조변수에 자식 인스턴스를 참조)가능 여부가 달라지게 된다.
아래 그림과 같이 같이 GoldBox< Integer> 인스턴스를 부모인 Box< Integer>에 참조 가능하다.
그러나 Box< String>형 참조 변수에는 참조가 불가능하다.
Box<Integer> iBox = new GoldBox<>(7959); // 참조 가능
Box<String> sBox = new GoldBox<>(1234); // 참조 불가능
❗️ T 에 전달되는 클래스 타입이 동일해야 참조가 가능하다
제네릭 메소드를 호출할 때< Integer>라고 명시하지 않더라도 T를 특정지을 수 있는 대상인 Box< Intger> 를 타겟 타입이라고 한다.
class EmptyBoxFactory{
public static <T> Box<T> makeBox(){
Box<T> box = new Box<T>();
return box;
}
}
public static void main(String[] args) {
Box<Integer> ibox = EmptyBoxFactory.<Integer>makeBox();
// Box<Integer> ibox = EmptyBoxFactory.makeBox(); // <Integer>를 명시하지 않아도 컴파일러가 인식한다.
}
위와 같이 새로운 박스를 생성해주는 제네릭 메소드가 호출될 경우 주석 처리한 코드처럼 컴파일러는 Box< Integer>를 기반으로 Box< Integer>형 참조변수에 참조를 허용해준다.
이렇게 < Integer>라고 명시하지 않더라도 T를 특정지을 수 있는 대상
즉, Box< Intger>를 타겟 타입이라고 한다.
타겟타입이라는 용어 자체는 자주 쓰이지는 않아 크게 중요하지는 않지만, 이런게 있구나 알아두기만 하자.
Integer가 Object를 상속하고 있더라도 Box< Integer>와 Box< Object>는 전혀 다른 두개의 클래스다.
따라서 Box< Object>를 인자로 받는 메소드에 Box< Integer> 인스턴스를 인자로 전달할 수 없다.
public static <T> Box<T> peekBox(Box<T> box) {
System.out.println(box);
}
위 제네릭 메소드는 매개변수로 Box< Integer> Box< String> 같이 T에 전달되는 클래스에 따라 다양한 클래스를 매개변수로 전달 가능하다.
public static void peekBox(Box<Object> box) {
System.out.println(box);
}
제네릭의 상속을 공부할 때 Box< T> 에서 T에 전달되는 클래스에 따라 상속 가능 여부가 달라졌다.
언뜻 보기에 위 메소드는 Object가 Integer를 상속하기에 아래와 같이 매개변수로 Box< Integer>를 전달할수 있을 것 같지만,
Box<Integer> ibox = EmptyBoxFactory.makeBox();
// peekBox(ibox); // 매개변수로 ibox 전달 불가능
}
Box< Object> 와 Box< Integer>는 사실상 아예 다른 클래스이기 때문에 매개변수로 전달이 불가능하다.
참고