[개발일지] 230524 제네릭 상속 (with 와일드카드)

오늘은 제네릭과 와일드카드를 활용해 클래스를 상속해 다형성 특징을 살리는 코드를 작성해 봤다.

 

오늘 새로 배운 내용

<?>

 

이는 우리가 흔히 알고 있는 와일드카드이다. 

와일드카드는 특정 타입을 명시해주지 않고 모든 타입이 올 수 있다는 것을 의미한다.

 

예를 들어 Set <?>처럼 선언을 해주면 해당 Set에는 어떤 타입이든지 담을 수 있는 Set이 된다.

 

 

<? extends T>

 

와일드카드에 extends와 T라는 제네릭을 사용해 범위를 제한한 것이다. extends 키워드를 사용해 T의 상위 클래스들을 제한한다는 의미이다.

다시 말해 T의 부모 클래스들은 제한이 되고 T와 T의 자식 클래스들만 오도록 제한하는 것이다.

 

 

<? super T>

 

반대로 super는 T의 하위 클래스를 제한하여 T와 T의 상위 클래스들만 오도록 제한하는 것이다.

 

 

 

범위를 제한함으로써 얻을 수 있는 이점

 

그냥 <?> 와일드카드만 사용해서 모든 타입이 올 수 있도록 명시하는 것보다 <? extends T>처럼 제네릭을 이용해 범위를 제한해 주면 T타입 또는 여기서는(extends) T의 하위타입이 컬렉션에 추가될 때 타입이 호환되는 것이 보장이 된다는 이점이 있고, T 타입 또는 하위 타입의 요소를 허용하는 컬렉션이나 메서드로 작업해야 할 때 유용하다.

 

 

로 타입은 사용하지 말자

 

제네릭이 등장하고 기존 코드와의 호환성 때문에 만들어진 로 타입(제네릭 타입에서 타입 매개변수가 없는 것)의 사용은 지양해야 한다.

 

예를 들어 List <String>처럼 타입 매개변수에 String을 써준 것과 달리 로 타입은 List 이 형태이다. 즉 List에 어떤 객체를 넣어도 컴파일 시점에서는 오류가 발생하지 않는다. 

 

로 타입을 사용하게 되면 제네릭의 장점인 타입 안정성을 잃게 된다.