안드로이드 개발자의 창고
[16일차 Kotlin] Generic 본문
출처 : 안드로이드 앱스쿨 2기 윤재성 강사님 수업 PPT
📖 Generic
- 클래스를 설계할 때 변수의 타입을 유동적으로 하고 싶을 때가 있을 수도 있다.
- 이 때 Generic 개념을 활용하면 클래스 작성시가 아닌 객체 생성 시에 변수의 타입을 설정할 수 있다.
가변성
- 불변성 : Generic이 설정된 객체의 주소 값을 같은 타입의 제네릭이 설정된 변수에만 담을 수 있다.
- 공변성 : Generic이 설정된 객체의 주소 값을 부모 클래스 타입의 제네릭이 설정된 변수에도 담을 수 있다(out)
- 반 공변성 : Generic이 설정된 객체의 주소 값을 자식 클래스 타입의 제네릭이 설정된 변수에도 담을 수 있다(in)
📖 예제 코드
Generic이 설정된 Class
class TestClass1<T>{
fun testMethod1(a1:T){
println("a1 : $a1")
}
}
class TestClass2<T>(var a1 : T){
fun testMethod2(a2 : T){
println("a1 : $a1")
println("a2 : $a2")
}
}
class TestClass3<A, B, C, D>(var a1:A, var a2:B){
fun testMethod3(a3:C, a4:D){
println("a1 : $a1")
println("a2 : $a2")
println("a3 : $a3")
println("a4 : $a4")
}
}
✔️ 코드 해석
- < > : 안에 알파벳 문자를 넣어준다. 보통 대문자 한글자를 작성한다.
- 이 알파벳은 아직 결정되지 않은 타입을 의미한다.
- 어떠한 타입인지 결정되지 않았지만 이 타입의 변수들을 정의하여 클래스를 작성하고, 객체를 생성할 때 타입을 결정할 수 있다.
Generic 클래스를 이용한 코드
fun main(){
val t1 = TestClass1<Int>()
t1.testMethod1(100)
val t2 = TestClass1<String>()
t2.testMethod1("안녕하세요")
val t3 = TestClass2<Int>(100)
t3.testMethod2(200)
val t4 = TestClass2<String>("문자열1")
t4.testMethod2("문자열2")
val t5 = TestClass3<Int, Double, Boolean, String>(100,11.11)
t5.testMethod3(true, "문자열1")
val t6 = TestClass3<Double, String, Boolean, Int>(22.22, "문자열2")
t6.testMethod3(false, 200)
}
✔️ 코드 해석
- Generic이 정의된 클래스를 가지고 객체를 생성한다.
- Generic 타입의 타입을 결정한다.
Generic 불변성, 공변성, 반 공변성 예제 클래스
open class SuperClass1
open class SubClass1 : SuperClass1()
class SubClass2 : SubClass1()
// 불변성
class TestClass5<A>()
// 공변성
class TestClass6<out A>()
// 반 공변성
class TestClass7<in A>()
main 예제 코드
fun main(){
val t7:TestClass5<SubClass1> = TestClass5<SubClass1>()
// val t8:TestClass5<SuperClass1> = TestClass5<SubClass1>()
// val t9:TestClass5<SubClass2> = TestClass5<SubClass1>()
val t10:TestClass6<SubClass1> = TestClass6<SubClass1>()
val t11:TestClass6<SuperClass1> = TestClass6<SubClass1>()
// val t12:TestClass6<SubClass2> = TestClass6<SubClass1>()
val t13:TestClass7<SubClass1> = TestClass7<SubClass1>()
// val t14:TestClass7<SuperClass1> = TestClass7<SubClass1>()
val t15:TestClass7<SubClass2> = TestClass7<SubClass1>()
}
✔️ 코드 분석
- val t7:TestClass5<SubClass1> = TestClass5<SubClass1>()
- 불변성 : 객체를 생성할 때 설정한 Generic과 같은 변수에 담을 수 있다.
- 클래스 간의 관계에 상관 없이 Generic에 설정한 클래스 타입이 다르면 오류가 발생한다.
- 따라서 해당 코드 밑에 있는 t8과 t9는 오류가 발생한다.
- val t11:TestClass6<SuperClass1> = TestClass6<SubClass1>()
- TestClass6은 out 키워드를 사용했다.
- 공변성 : 변수에 설정한 Generic이 객체를 생성했을 때 사용한 Generic의 부모 클래스인 경우에도 담을 수 있다.
- 따라서 t11은 가능하지만 t12는 오류가 발생한다.
- val t15:TestClass7<SubClass2> = TestClass7<SubClass1>()
- TestClass7은 in 키워드를 사용했다.
- 반 공변성 : 변수에 설정한 Generic이 객체를 생성했을 때 사용한 Generic의 자식 클래스인 경우에도 담을 수 있다.
'Computer > Kotlin' 카테고리의 다른 글
[16일차 Kotlin] Null 처리(!! 연산자, ?: 연산자, ?. 연산자) (0) | 2023.05.20 |
---|---|
[16일차 Kotlin] 중첩 클래스 (0) | 2023.05.19 |
[16일차 Kotlin] Data Class (0) | 2023.05.18 |
[16일차 Kotlin] Companion (0) | 2023.05.18 |
[15일차 Kotlin] 인터페이스(Interface) (0) | 2023.05.17 |