- μ΄ κΈμ "μ€μ¬μ±μ Google 곡μ μΈμ΄ Kotlin" κ°μλ₯Ό λ£κ³  곡λΆν λ΄μ©μΌλ‘ μμ±νμμ΅λλ€.
 
Generic ν΄λμ€
- ν΄λμ€λ₯Ό μ€κ³ν  λ κ°μ μν μ νμ§λ§ λ΄λΆμ λ³μμ νμ
λ§ λ€λ₯΄κ² νμν  λκ° μμ΅λλ€.
 
- Generic ν΄λμ€λ₯Ό νμ©νμ¬ ν΄λμ€ μμ± μκ° μλ κ°μ²΄λ₯Ό μμ±μμ νμ
μ μ§μ ν  μ μμ΅λλ€.
 
- Genericμ μ¬μ©νλ©΄ λ°μ΄ν° νμ
μ μ»΄νμΌ νμμ μ νκΈ° λλ¬Έμ ν΄λμ€λ λ©μλ λ΄λΆμ μ¬μ©λ  λ°μ΄ν°μ νμ
 μμ μ±μ λμΌ μ μμ΅λλ€.
 
- λνμ μΈ μλ‘ Collection λ€μ λͺ¨λ Generice ν΄λμ€λ‘ μ μλμ΄ μμ΅λλ€.
 
- λ§μΌ Any ν΄λμ€λ‘ μΊμ€ν
ν΄μ μ¬μ©νλ€λ©΄ λ²κ±°λ‘κ³  μλͺ»λ μΊμ€ν
μΌλ‘ λ°νμμ μ€λ₯ λ°μ κ°λ₯μ±μ΄ μκΈ° λλ¬Έμ Genericμ μ¬μ©νμ¬μΌ ν©λλ€.
 
class ArrayList<T>(val param : T){
    fun print(){
        when(param){
            is String -> {
                println("ArrayList element's Type is String : $param")
            }
            is Int -> {
                println("ArrayList element's Type is Int : $param")
            }
            is Double -> {
                println("ArrayList element's Type is Double : $param")
            }
            else -> {
                println("ArrayList element's Type is Any")
            }
        }
    }
}
fun main(){
    val intArr = ArrayList(3)
    val stringArr = ArrayList("hello")
    val doubleArr = ArrayList(3.3)
    intArr.print()
    stringArr.print()
    doubleArr.print()
    /** result
    ArrayList element's Type is Int : 3
    ArrayList element's Type is String : hello
    ArrayList element's Type is Double : 3.3
    **/
}
- μμ μμ μ¬μ©λ Tλ₯Ό νμ
 λ³μλΌκ³  νλ©°, μμμ μ°Έμ‘°ν νμ
μ μλ―Έν©λλ€. νμ
μ λ§€κ°λ³μ μ΄λ¦μλ μ무거λ λ€μ΄κ°λ μκ΄μμ§λ§ 곡μλ¬Έμμ Name Conventionμ λ°λ₯΄λκ² μ’μ΅λλ€. [https://math-coding.tistory.com/184]
 
- Genericμ ν΄λμ€μ λ©μλλ₯Ό μ΄μΈμλ μΈν°νμ΄μ€μλ μ¬μ©μ΄ κ°λ₯ν©λλ€.
 
 
κ°λ³μ±
- λΆλ³μ± : Genericμ΄ μ€μ λ κ°μ²΄μ μ£Όμ κ°μλ μμ ν΄λμ€λ λΆλͺ¨ν΄λμ€κ° μλ μ€μ λ κ°μ νμ
μ λ³μμλ§ λ΄μ μ μμ΅λλ€. (λ€νμ± x)
 
- 곡λ³μ± : Genericμ΄ μ€μ λ κ°μ²΄μ μ£Όμ κ°μ out ν€μλλ₯Ό ν΅ν΄ λΆλͺ¨ ν΄λμ€ νμ
μ λ³μμ λ΄μ μ μμ΅λλ€. (μλ°μ bounded Type μ μ¬)
 
- λ° κ³΅λ³μ± : Genericμ΄ μ€μ λ κ°μ²΄μ μ£Όμ κ°μ in ν€μλλ₯Ό ν΅ν΄ μμ ν΄λμ€ νμ
μ λ³μμ λ΄μ μ μμ΅λλ€.
 
open class TestClass
open class TestSubClass : TestClass()
class TestSubSubClass : TestSubClass()
class GenericClass<T>
class GenericClass2<out T>
class GenericClass3<in T>
fun main(){
    // λΆλ³μ±
    val cls1: GenericClass<TestSubClass> = GenericClass<TestSubClass>()
    val cls2: GenericClass<TestSubSubClass> = GenericClass<TestSubClass>()    // Compile error
    val cl3: GenericClass<TestClass> = GenericClass<TestSubClass>()  // Compile error
    // 곡λ³μ±
    val cls4: GenericClass2<TestSubClass> = GenericClass2<TestSubClass>()
    val cls5: GenericClass2<TestSubSubClass> = GenericClass2<TestSubClass>()    // Compile error
    val cls6: GenericClass2<TestClass> = GenericClass2<TestSubClass>()
    // λ° κ³΅λ³μ±
    val cls7: GenericClass3<TestSubClass> = GenericClass3<TestSubClass>()
    val cls8: GenericClass3<TestSubSubClass> = GenericClass3<TestSubClass>()   
    val cls9: GenericClass3<TestClass> = GenericClass3<TestSubClass>()      // compile error
}
- λΆλ³μ± μμ μμλ μ λλ¦ νμ
μ μ€μ λ νμ
 λ³μλ₯Ό μ μΈνκ³ λ λΆλͺ¨ ν΄λμ€λ  μμ ν΄λμ€ λͺ¨λ μ»΄νμΌ μλ¬κ° λνλ κ²μ νμΈν  μ μμ΅λλ€.
 
- 곡λ³μ± μμ μμλ μ λλ¦ νμ
μ μ€μ λ νμ
 λ³μμ μ€μ λ νμ
μ μμ ν΄λμ€κΉμ§ ν¬ν¨νμ¬ λμ
μ΄ λλ κ²μ νμΈν  μ μμ΅λλ€. out ν€μλλ₯Ό μ¬μ©νλλ° ν·κ°λ¦¬μλ€λ©΄, Tκ° outνλ ν΄λμ€(λ΄λ³΄λ΄λ ν΄λμ€)λ λΆλͺ¨ ν΄λμ€λ‘λΆν° μμν΄λμ€κ° outλκΈ° λλ¬Έμ κ·Έλ κ² μ΄ν΄νμλ©΄ νΈν  κ² κ°μ΅λλ€.
 
- λ° κ³΅λ³μ± μμ μμλ μ λλ¦ νμ
μ μ€μ λ νμ
 λ³μμ μ€μ λ νμ
μ λΆλͺ¨ ν΄λμ€λ₯Ό ν¬ν¨νμ¬ λμ
μ΄ λλ κ²μ νμΈν  μ μμ΅λλ€. in ν€μλλ Tκ° inνλ ν΄λμ€(ν¬ν¨νλ ν΄λμ€)λ μμ ν΄λμ€μλ λΆλͺ¨ν΄λμ€λ₯Ό ν¬ν¨νκΈ° λλ¬Έμ λΆλͺ¨ ν΄λμ€λ₯Ό ν¬ν¨ν  μ μλ€κ³  μκ°νμλ©΄ λ©λλ€.
 
 
μ€μ²© ν΄λμ€
- ν΄λμ€ μμ μλ‘κ² μμ±λ ν΄λμ€λ₯Ό μ€μ²© ν΄λμ€λΌκ³  λΆλ¦
λλ€.
 
- μ€μ²© ν΄λμ€λ μΈλΆ ν΄λμ€μ λ©€λ² λ³μλ₯Ό μ½κ² μ κ·Όμ΄ κ°λ₯νκΈ° λλ¬Έμ μΈλΆ ν΄λμ€μ λ©€λ² λ³μλ₯Ό λ§μ΄ μ¬μ©νκ² λλ μ€κ³λ₯Ό νμ€ λ μ€μ²© ν΄λμ€λ₯Ό μ¬μ©νμλ©΄ λ©λλ€.
 
- μ€μ²© ν΄λμ€μμλ κ° ν΄λμ€μ μ μν λ©€λ²λ₯Ό μ¬μ©ν  μ μλκ°λ₯Ό μ ννκ² μμ§ν  νμκ° μμ΅λλ€.
 
class OuterClass{
    val outerMember = 100
    fun outerMethod(){
        println("OuterMethod $outerMember")
    }
    inner class InnerClass{
        val innerMember = 200
        fun innerMethod(){
            println("innerMethod $innerMember")
            println("outmember $outerMember")
            outerMethod()
        }
    }
}
fun main(){
    var cls = OuterClass()
    var innercls = cls.InnerClass()
    cls.outerMethod()
    innercls.innerMethod()
}
- inner ν€μλλ₯Ό μ¬μ©νμ¬ μ€μ²© ν΄λμ€λ₯Ό μ μν  μ μκ³ , inner classλ 무쑰건 outerclassμ κ°μ²΄λ₯Ό ν΅ν΄μλ§ μμ±ν  μ μμ΅λλ€. μ¦, inner ν΄λμ€λ₯Ό μ¬μ©νκΈ° μν΄μλ outerclassλ₯Ό μμ±ν΄μΌ ν©λλ€.
 
- inner ν΄λμ€λ outer ν΄λμ€κ° μμ±λ μ΄νμ μμ±μ΄ λκΈ° λλ¬Έμ outer ν΄λμ€μ μλ λ©€λ² λ³μμ λ©μλ λͺ¨λ μ¬μ©ν  μ μμ΅λλ€.
 
- outer ν΄λμ€μμλ inner ν΄λμ€ λ΄λΆμ λ©€λ² λ³μ, λ©μλλ₯Ό μ¬μ©ν  μ μλλ° outer ν΄λμ€λ§ μμ± μμ inner ν΄λμ€λ μμ±μ΄ λ κ²μ΄ μλκΈ° λλ¬Έμ μ κ·Όν  μ μλ κ²μ΄ λΉμ°ν©λλ€.
 
- λ§μΌ outer ν΄λμ€μμ inner ν΄λμ€μ λ©€λ² λ³μμ λ©μλμ μ κ·Όνκ³  μΆλ€λ©΄, μ§μ  inner ν΄λμ€λ₯Ό μμ±ν ν κ°μ²΄λ₯Ό ν΅ν΄μ μ κ·Όνλ©΄ λ©λλ€.