일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | |||||
3 | 4 | 5 | 6 | 7 | 8 | 9 |
10 | 11 | 12 | 13 | 14 | 15 | 16 |
17 | 18 | 19 | 20 | 21 | 22 | 23 |
24 | 25 | 26 | 27 | 28 | 29 | 30 |
- PrototypePattern
- Singleton
- 팩토리 메소드
- 추상 팩토리
- 프로토타입 패턴
- Functional Programming
- 빌터패턴
- designPattern
- builderPattern
- 추상팩토리패턴
- F
- Abstract Factory
- ㅋㅁ
- 디자인패턴
- r
- a
- 코틀린
- Kotlin
- Observer Pattern
- El
- 디자인패턴 #
- 싱글톤
- Design Pattern
- 함수형프로그래밍
- 옵저버 패턴
- factory method
- ㅓ
- Today
- Total
오늘도 더 나은 코드를 작성하였습니까?
반공변성: 뒤집힌 하위 타입 관계 본문
반공변 클래스의 하위 타입 관계는 공변 클래스의 경우와 반대이다.
Comparator 인터페이스 살펴보기.
interface Comparator<in T>{
fun compare(e1: T, e2: T): Int
}
이 인터페이스는 T타입의 값을 소비하기만 한다. 따라서 타입 파라미터 앞에 in을 붙혀야 한다.
물론 특정 타입에 Comparator을 구현하면, 그 타입의 하위 타입에 속하는 모든 값을 비교할 수 있다.
fun main() {
val anyComparator = Comparator<Any> { e1, e2 ->
e1.hashCode() - e2.hashCode()
}
val strings = listOf<String>("a", "b", "c")
strings.sortedWith(anyComparator) // 문자열과 같은 구체적인 타입을 비교하는데 모든 객체를 비교하는 AnyComparator을 사용할 수있다.
}
sortedWih는 Comparator<String>을 요구하기 때문에 조금 더 일반적인 타입을 비교 가능한, Comparator을 넘겨주는 것은 안전하다
그 타입이나 조상 타입을 비교할 수 있는 Comparator을 사용할 수 있다.
이는 Comparator<Any>가 Comparator<String>의 하위 타입이다.
Comparator<String>가 필요한 위치에 Comparator<Any>가 들어가도 되기 때문이다.
하지만 Any는 String의 하위 타입이다. 서로 다른 타입인자에 대해서 Comparator의 타입이 뒤바뀌게 된다.
타입 B가 타입 A의 하위 타입인 경우 Consumer<A>가 Consumer<B>하위 타입 관계가 성립되면
Consumer<T>는 타입 인자 T에 있어 반공변이다.
in 키워드는 그 키워드가 붙은 타입이 메소드 안으로 전달되어 소비된다는 뜻이며,
타입 파라미터의 사용을 제한함으로써 특정 하위 타입관 관계에 도달할 수 있다.
클래스나 인터페이스가 특정 타입 파라미터에 대해서는 공변적이고 다른 타입 파라미터에 대해서는 반공변적일 수도 있다.
interface Function1<in P, out R>{
operator fun invoke(p: P): R
}
(P) -> R 는 Function<P, R>을 좀 더 알아보기 쉽게 적은것 이다.
Function1 은
첫번째 타입 파라미터와는 하위타입이 반대인 반공변적이고
두번째 타입 파라미터와는 하위타입이 동일한 공변성을 가진다.
예를들면
open class Animal(val birthDay: Int)
fun Animal.getIndex(): Int = birthDay
class Cat(val name: String): Animal(name.hashCode())
fun enumerateCats(f: (Cat) -> Number){
println(f.invoke(Cat("나비")))
}
fun main() {
enumerateCats(Animal::birthDay)
}
Animal은 Cat의 상위 타입이지만, 반공변적으로 in 위치이고
numbers는 int의 상위타입으로 공변적으로 out의 위치이다.
'Kotlin in Action > 코틀린 답게 사용하기' 카테고리의 다른 글
스타 프로젝션 (0) | 2021.03.04 |
---|---|
사용 지점 변성: 타입이 언급되는 지점에서 변성지정 (0) | 2021.03.03 |
변성: 제네릭과 하위 타입2 (0) | 2021.03.02 |
변성: 제네릭과 하위 타입 (0) | 2021.03.02 |
실행시 제네릭스의 동작 (0) | 2021.03.02 |