마스터Q&A 안드로이드는 안드로이드 개발자들의 질문과 답변을 위한 지식 커뮤니티 사이트입니다. 안드로이드펍에서 운영하고 있습니다. [사용법, 운영진]

(코틀린) 코드 관련 질문입니다

+1 추천
abstract class UseCase <Type, in Params>(private val apiErrorHandle: ApiErrorHandle) where Type: Any

위 코드에서 <Type, in Params> 이 부분이 의미하는 것과 where Type: Any 이 부분이 의미하는 것이 궁금합니다. 답변주시면 감사하겠습니다.
주녕녕 (290 포인트) 님이 2020년 10월 20일 질문

1개의 답변

+1 추천
 
채택된 답변

<Type, in Param>는 Generic 타입이라혹 하는데 Type은 그냥 어떤 타입을 가리키는 기호에 불과합니다. 예를 들면 List가 대표적인 Generic을 사용하는 클래스입니다. List<T>로 선언되어 있습니다. 여기서 T는 아무런 의미가 없어요. 그냥 어떤 타입이 올거라는 의미입니다. List안에 String 타입만 담고싶다면 List<String, Int만 담고 싶다면 List<Int>, Person클래스만 담고 싶다면 List<Person>으로 사용하시면 됩니다.
 

val stringList: List<String> = arrayListOf()
stringList.add("Hello world") (o)
stringList.add(99) (x) - compile error

Generic은 실제로는 타입이 정해져 있지 않고, 사용할 때 주어지는 타입을 사용하게 됩니다. 뒤의 Param도 마찬가지구요. 예를들면,

class MyUseCase: UseCase<String, Int>

class MyUseCase: UseCase<List<String>, Boolean>

처럼, 어떤 타입이든지 들어갈 수 있습니다. 그리고 in은 Param 타입의 하위 타입이라는 의미입니다. 예를 들면,

interface Expr<in T> {
   fun eval(): T
}

Class NumberExpr: Expr<Number> {
     override fun eval(): Double {  

     }
}

이렇게 하면,  Double은 Number의 하위 타입이므로 사용이 가능합니다. Int, Float, Long 이런 타입들도 Number의 하위타입이므로 eval 함수의 리턴타입으로 사용할 수 있겠죠. out을 쓰면 그 반대구요.

Any는 모든 Class의 최상위 타입, 즉 Java Object type이라고 보시면 될 것 같구요.  where 키워드를 사용하면 UseCase의 Type이 뭔지 모를 때 Type은 Any 타입이 된다고 알려주는 것입니다. 즉 
 

abstract class UseCase<Type, in Param> where Type: Any {
    abstract fun execute(P: Param): Type
}

class MyUseCase: UseCase<List<*>, String>() {
    override fun execute(P: String): List<*> {

    }
}

List<*>는 List<Any>로 간주됩니다. 그런데 님의 예제에서는 굳이 where절은 필요가 없어 보이네요.

spark (224,800 포인트) 님이 2020년 10월 20일 답변
주녕녕님이 2020년 10월 21일 채택됨
답변해주셔서 정말 감사합니다ㅠ 덕분에 궁금한 게 해결됐습니다
...