코틀린 제네릭(extends=out/super=in)

Koder·2023년 1월 16일
0

단순히 정의가 없는 제네릭은 한정자(variance)가 없기에 이를통해 생성 되었어도
어떠한 관련성을 갖지 않음을 뜻합니다.

class Animal<T> 

만약에 관련성을 가져야 한다면 한정자(variance) in,out을 정의해야 합니다.
코틀린에서 취급하는 out과 in은 한정자(variance)라고 불려집니다.

한정자(variance) - 방향만 다를뿐 위/아래

  • out: 제시된 타입에 속한것 (extends)
  • in: 제시된 타입에 속한것 (super)

out(extends)를 사용하는 경우

class Animal<out T> // extends
open class Dog
class Puppy: Dog()

val a: Animal<Dog> = Animal<Puppy>() // 성공: Puppy는 Dog보다 하위에 속하여 다운캐스팅
val b: Animal<Puppy> = Animal<Dog>() // 오류: Puppy를 기준으로 하위 Require를 하는대 상위 타입이다.

in(super)를 사용하는 경우

class Animal<in T> // super
open class Dog
class Puppy: Dog()

val a: Animal<Dog> = Animal<Puppy>() // 오류: Dog를 기준으로 상위 타입이 와야하는대 하위인 Puppy가 잡혀 업캐스팅 불가
val b: Animal<Puppy> = Animal<Dog>() // 성공: Dog는 Puppy보다 상위에 속하여 업캐스팅

컴파일상에 문제는 없지만 추천하지 않는 방식

open class Animal
interface Bird
class Eagle: Animal(), Bird

val a: Animal = Eagle() // 성공: Eagle을 Animal으로 업캐스팅(클래스)
val b: Bird = Eagle() // 성공: Eagle을 Bird으로 업캐스팅(인터페이스)

한정자(varance)가 아닌 인터페이스로 업캐스팅을 하는경우에 동작에는 문제는 없지만
가급적 가능하다면은 한정자로 구분을 지어주는게 유지보수에 유리하고 명확하기 때문에 권장됩니다.
물론 인터페이스를 사용하는게 최적인 경우에는 피할수 없겠지만 작업자가 최적의 선택을..ㅎㅎ

profile
일단 적고 보자

0개의 댓글