Coding Memo

Kotlin 캐스팅 본문

Language/Kotlin

Kotlin 캐스팅

minttea25 2021. 1. 6. 12:48

클래스 간 캐스팅은 Kotlin의 클래스의 다형성과 관련이 있다.

 

A 클래스가 B 클래스를 상속받을 경우, A 클래스는 B 클래스의 객체 공간이 있고 자신만의 A 클래스 객체 공간이 따로 있다.

 

다음의 예시를 보자.

fun main() {
    var c: A = A()
    var d: A = B()
    var e: B = B()

    c.printName()
    d.printName()
    e.printName()
    e.printName2()
}

open class A() {
    open var name: String = "ClassA"
    open fun printName() {
        println("$name")
    }
}

class B : A() {
    override var name: String = "ClassB"
    override fun printName() {
        println("$name")
    }
    fun printName2() {
        println("${name}2")
    }
}

d 라는 변수는 A 타입으로 선언했는데 B라는 클래스를 넣었다.

B가 A를 상속받고 있기 때문이다.

 

여기서 A가 B보다는 상위 자료형이 되고, d 변수에서 B 클래스가 up-casting 되어 자동으로 A 타입의 변수에 들어간다.

예시에서 보이듯이 up-casting은 별도 연산자가 필요하지 않다.

 

그러나 down-casting은 별도 연산자가 필요하다.

down-casting 연산자에는 2가지가 있다.

 

as: 호환 가능한 자료형(타입)으로 변환시켜주고 반환해준다.

 

is: 변수가 자료형(타입)에 호환되는지 확인 후 변환까지 시켜준다.

 

fun main() {
    var c: A = B()
    c.printName()
    //c.printName2()  불가

    if (c is B) {
        c.printName2() //가능
    }
    //c.printName2() 불가

    var d: A = B()
    d as B //단순히 이렇게 써도 된다.
    d.printName()
    d.printName2() //위에서 d as B 가 실행되었기 때문에 가능한 구문

    var e: B = c as B //이렇게 반환 값을 줄 수도 있다.
    e.printName()
    e.printName2()
}

casting 예시 출력 결과

'd as B'처럼 단순히 d를 B 타입으로 캐스팅시킬 수도 있고, 'var e: B = c as B' 처럼 반환 값을 통해 값을 할당할 수도 있다.

is 관련해서 테스트해본 결과, is의 효력은 if문 내부에서만 발생하는 것으로 보인다. if문 블록을 벗어나고 printName2() 함수를 호출하려고 하자 에러가 발생했다.

 

참고: 캐스팅 연산자는 프로그램 속도를 느리게 할 수도 있다고 한다. 따라서 C++과 Java에도 있는 Generic이 Kotlin에도 있으므로 이것을 사용하는 것이 좋을 거 같다.

'Language > Kotlin' 카테고리의 다른 글

Kotlin null 값  (0) 2021.01.06
Kotlin 제네릭  (0) 2021.01.06
Kotlin 문자열  (0) 2021.01.05
Kotlin 옵저버 패턴  (0) 2021.01.03
Kotlin 오브젝트  (0) 2021.01.03