ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • [Kotlin] TypeCasting
    Kotlin 2022. 9. 14. 15:51

    기본 자료형 클래스 간의 형변환

    fun main() {
        var a1:Int = 100
        //var a2:Double = a1 -> error
        var a2:Double = a1.toDouble()
    
        var b1:Double = 123.12
        // var b2:Int = b1
        var b2:Int = b1.toInt()
    
        var c1:String = "12234"
        var c2:Int = c1.toInt()
    
        var d1:String = "122.34"
        var d2:Double = d1.toDouble()
    
        // val d3:String = "안녕하세요"; val number4:Int = d3.toInt() -> error
    }

     

    fun main() {
    // 1. 부모 클래스 참조변수에 자식 클래스의 인스턴스를 저장
        // 스마트 캐스팅 발생
        val super1:SuperClass4 = SubClass41() // SuperClass: 부모클래스, SubClass41:자식
        // 스마트 캐스팅 발생
        val inter1:Inter4 = SubClass42() //  Inter4: 부모인터페이스, SubClass42: 자식클래스
    
    
    // 2. 자식 인스턴스가 부모래퍼런스 변수에 저장되었다가 다시 자식래퍼런스변수로 옮겨 저장될 때,
    //    강제캐스팅이 필요하다는건 자바나 코틀린이나 같음.
    //    옮겨지는 인스턴스는 반드시 자식인스턴스여야하는 제약과 똑같음. 
    //    다만 코틀린과 자바의 명령이 달라짐.
    
        // 자바 문법
        // val sub1:SubClass41 = (SubClass41)super1
        // val sub2:SubClass42 = (SubClass42)inter1
    
        // 코틀린에서 자식인스턴스를 담고 있는 부모래퍼런스 변수값이 자식래퍼런스 변수로 이동할 때
        super1 as SubClass41    // 자바의 super1 = (SubClass41)super1 명령과 같음
        inter1 as SubClass42    // 자바의 inter1 = (SubClass42)inter1 명령과 같음
        // 위 명령은 super1과 inter1에 있는 레퍼런스 값을 옮기려는 자식 클래스 자료형의
        // '다른 변수에 형변환 과 함께 옮기는 것이 아니라' 해당 자료형으로 변경시켜버림.
        // 이 명령 이후 super1 변수의 자료형은 SubClass41이 되고 
        // inter1 변수의 자료형은 SubClass42가 됨
        // '새로운 자식 클래스 레퍼런스 변수'로 값을 옮겨 담는 것이 아니라, 저장된 참조값을 놔두고
        // '현재 변수의 자료형을 변경'해 버린다는 뜻
        println("변경 후 super1 : $super1")
        println("변경 후 inter1 : $inter1")
        // 형변환의 유효영역은 as 명령을 감싸고 있는 중괄호 안쪽임
    
        // 자바의 경우 위 두개의 경우 형변환전에 안전한 실행을 위해 점검을 했음
        // if( super1 instanceof SubClass41 ) {
        //      val sub1:SubClass41 = (SubClass41)super1  //형변환 명령
        //  }
        // 코틀린에서는
        // if( super1 is SubClass41 ){
        //    super1 as SubClass41 // 코틀린 강제 형변환 명령
        // }
    
        // 먼저 자식 인스턴스를 부모레퍼런스에 저장
        val super2:SuperClass4 = SubClass41()
        val inter2:Inter4 = SubClass42()
    
        // 다시 부모레퍼런스가 저장하고 있는 자식인스턴스를 자식 레퍼런스에 옮길텐데,
        // 위에서 언급한거 처럼 코틀린은 옮기지않고, 레퍼런스 변수 자체를 변경해버립니다
        // 그전에 변경이 가능하지 검사
        if( super2 is SubClass41 ){
            super2 as SubClass41  // if문의 중괄호 밖에서도 형변환 결과를 활용할수 있습니다.
        } else {
            println("형변환이 불가능합니다.")
        } // 검사결과가 참이면 변환, 거짓이면 변환하지 않음
    
    
        if( inter2 is SubClass42 ){
            // is 에 의해 열린 if 문 안에서는  as 를 쓰지 않아도
            // is 연산자 값이 true라면 형변환이 가능한 상황이므로 자동으로 스마트 캐스팅 실행됨
            // 현재위치 중괄호 { } 안에는 이미  inter2 는 SubClass42의 레퍼런스로 변경된 상태이며 
            // 그 상태로 사용이 가능
            // 다만  중괄호를 벗어나면  다시  Inter4(부모인터페이스)의 레퍼런스로 되돌아감
            // 중괄호가 끝나도 계속 변경 상태를 유지하려면 inter4 as SubClass42를 사용함
        }
    
    }
    open class SuperClass4
    interface Inter4
    
    class SubClass41 : SuperClass4(){
        fun subMethod1(){
            println("SubClass21의 subMethod1입니다")
        }
    }
    class SubClass42 : Inter4{
        fun subMethod2(){
            println("SubClass21의 subMethod2입니다")
        }
    }

    'Kotlin' 카테고리의 다른 글

    [Kotlin] Map  (0) 2022.09.14
    [Kotlin] List  (0) 2022.09.14
    [Kotlin] Companion  (0) 2022.09.14
    [Kotlin] Interface  (0) 2022.09.14
    [Kotlin] Abstract  (0) 2022.09.14

    댓글

Designed by Tistory.