본문 바로가기

Kotlin/Basic

Kotlin - 클래스의 다형성 (Polymorphism)

내가 코틀린을 배우면서 코틀린에 있어 특별하다고 생각되는 부분들 또는 메모해두어야 할 점들을 여기에 적어놓으려고 한다.

 

Up-Casting과 Down-Casting

가령 상위클래스인 Drink 클래스가 있고, 하위클래스인 Cola 클래스가 있다고 하자. 이후, Cola의 인스턴스를 만들고 싶은데, 이 안에 Drink의 요소들만 담고 싶다면, 다음과 같이 선언하여 인스턴스를 생성할 수 있다. 이 경우에, Cola를 통하여 인스턴스를 생성했음에도, 해당 변수의 실질적인 인스턴스는 Drink의 인스턴스가 되게 된다.

 

fun main() {
    var cocaCola: Drink = Cola()
    cocaCola.sip()
    //cocaCola.shake()
}

open class Drink {
    fun sip() {
        println("sipping")
    }
}

class Cola: Drink() {
    fun shake() {
        println("boom")
    }
}

 

위 예시는 sip은 정상적으로 작동하지만, 주석을 제외하고 shake를 실행시키면 Unresolved reference: shake 에러가 난다.

 

이러한 방식을 상위 자료형인 수퍼클래스로 변환한다고 하여 Up-Casting이라고 하고, Up-Casting된 인스턴스를 다시 하위자료형으로 변환하면, 그걸 Down-Casting이라고 한다. Up-Casting은 위와 같이 간단하게 상위클래스로 선언하는 것만으로 가능하지만, Down-Casting을 하기 위해서는 별도의 연산자가 필요한데, 바로 as 와 is 연산자이다.

 

as는 자료를 호환되는 자료형으로 변환해주는 캐스팅 연산자로, 코드 내에서 사용시 즉시 자료형을 변환해준다. 또한, 변환된 결과를 반환하기 때문에, 다른 변수에 넣을 수도 있다. 이 경우 객체 자체는 같은 객체를 참조하게 되므로, 새로운 인스턴스의 생성이 아닌 객체 주소의 복사가 된다. 아래와 같이 사용할 수 있다.

 

예시

 

fun main() {
    var cocaCola: Drink = Cola()
    
    cocaCola as Cola
    cocaCola.shake()
}

open class Drink {
    fun sip() {
        println("sipping")
    }
}

class Cola: Drink() {
    fun shake() {
        println("boom")
    }
}

 

출력

 

boom

 

is는 변환이 가능한지 먼저 체크한 후 변환해주는 캐스팅 연산자로, 조건문 내에서 사용되는 특징이 있다. is는 조건문 내에서만 잠시 다운캐스팅이 된다. 즉, 완전히 변환시켜주는 것이 아니다. 예를 들어 아래의 예시를 보자면,

 

fun main() {
    var cocaCola: Drink = Cola()
    if (cocaCola is Cola) {
        cocaCola.shake()
    }
//     cocaCola.shake()
}

open class Drink {
    fun sip() {
        println("sipping")
    }
}

class Cola: Drink() {
    fun shake() {
        println("boom")
    }
}

 

boom이 잘 출력되지만, 주석처리를 제하고 나면, 에러가 뜬다.

 

출처

https://www.youtube.com/playlist?list=PLQdnHjXZyYadiw5aV3p6DwUdXV2bZuhlN