엔지니어 규의 IT 프로그래밍 다이어리

[Kotlin] 17. 클래스의 다형성 본문

프로그래밍 언어/코틀린

[Kotlin] 17. 클래스의 다형성

엔지니어 규 2022. 5. 23. 23:22
728x90

우리는 클래스의 상속을 통해 클래스를 '확장' 하는 방법을 배운적이 있다. 하지만 클래스를 다형성의 관점에서 살펴본적은 없다.

 

예를 들어 음료를 마시는 일에 비유를 해보자.

 

그냥 목이말라 아무음료나 마셔도 될때도 있지만 기호에 맞춰 콜라,생수,커피 등 원하는 음료를선택할 때도 있다.

 

이때 콜라를 '콜라 자체' 로도 볼수 있지만 '음료라는 특성' 으로도 볼 수 있도록 만드는 것이 다형성의 개념이다.

 

코틀린의 내부동작을 살펴보자.

 

 '음료' 라는 클래스와 이를 상속받은 '콜라'라는 클래스가 있다면 콜라의 인스턴스를 만들때

상속관계에 있는 super class 인 음료라는 객체를 담는공간에 콜라의 내용을 담는 내용이 추가되어 생성된다.

 

이렇게 만들어진 콜라의 인스턴스는 음료를 담는 변수에 저장하면 음료의 기능만 사용가능하고

콜라를 담는 변수에 저장하면 콜라의 기능까지 다 사용이 가능하다.

fun main(){

    var a= Drink()
    a.drink()
    var b : Drink = Cola()
    b.drink()


}

open class Drink {
    var name = "음료"
    open fun drink(){
        println("${name}를 마십니다.")
    }
}

class Cola : Drink(){
    var type = "콜라"
    override fun drink(){
        println("${name} 중에 ${type}를 마십니다.")
    }
    fun washDishes(){
        println("${type}로 설거지를 합니다.")
    }
}

음료를 마십니다.
음료 중에 콜라를 마십니다.

 

이때 콜라 인스턴스를 음료변수에 담는 행위를 상위 자료형인 수퍼클래스로 변환한다고 하여 

up-casting 이라고 하고, up-casting된 인스턴스를 다시 하위 자료형으로 변환하면 down-casting 이라고 부른다.

 

up-casting은 그냥 상위자료형에 담는것으로 동작하지만 down-casting은 '별도의 연산자'가 필요하다.

그 연산자는 as 와 is 라는 연산자이다.

 

 

'as'변수를 호환되는 자료형으로 변환해주는 캐스팅 연산자로, code 내에서 사용할 시 즉시 자료형을 변환해주며,

변환된 자료형을 반환도 해주는 연산자 이다.

 

 

'is'는 변수가 자료형에 호환되는지 먼저 체크한후 변환해주는 캐스팅 연산자로 조건문 내에서 사용되는 특징이 있다.

 

여기서 var b 는 Drink의 변수이므로  override 한 fun drink() 는 작동하지만  washDishes는 바로 작동이 불가능하다.

아래의 코드에서 b.washDishes() 는 unsolved reference 에러를 반환한다.

fun main(){

    var a= Drink()
    a.drink()
    var b : Drink = Cola()
    b.drink()

    b.washDishes() //unsolved reference : washdishes

}

 

이러한 상황에서 is 나 as 를 통해 다운캐스팅을 해야한다. 아래의 코드를 보자.

fun main(){

    var a= Drink()
    a.drink()
    var b : Drink = Cola()
    b.drink()


    if (b is Cola)
    {
        b.washDishes()   //콜라로 설거지를 합니다.
    }

    var c = b as Cola
    c.washDishes()  //콜라로 설거지를 합니다.
    b.washDishes()  //콜라로 설거지를 합니다.


}

 

 

if (b is cola) 에서 처럼 is 를 쓰면  조건문 안에서만 잠시 다운캐스팅이 된다. ( if 구문 밖에서 b.washDishes 를 쓰면 또 error가 난다.)

 

하지만 var c = b as Cola 로 다운캐스팅 한것을 변수 c에 할당하면 지속적으로 다운캐스팅이 된다.

이렇게 c 에 다운캐스팅 한것을 할당한 이후에 b.washDishes() 를 적으면  unsolved reference 에러가 나지 않는다.

as 를 사용하면 반환값(c) 뿐만 아니라 변수 자체 (b) 도 함께 다운캐스팅이 되기 때문이다.

 

다형성은 클래스의 상속관계에서 오는 인스턴스의 호환성을 적극 활용할 수 있는 기능으로

수퍼클래스가 같은 인스턴스를 한번에 관리하거나 인터페이스를 구현하여 사용하는 코드에서도 구현이된다.

 

 

 

728x90
Comments