기록
[코틀린/Kotlin] 클래스의 다형성 (as, is) 본문
'클래스의 상속'을 통해 클래스를 '확장'하는 법을 배운 바 있다.
클래스를 다형성의 관점에서 살펴보면 어떨까?
목이 말라서 아무 음료나 마셔도 좋을 때도 있지만 기호에 맞춰 콜라, 커피 등 원하는 음료를 선택할 때도 있다.
이때 콜라를 콜라 자체로도 볼 수 있지만, 음료라는 특성으로도 볼 수 있도록 만드는 것이 다형성의 개념이다.
음료 클래스와 이를 상속받는 콜라 클래스가 있다면, 콜라 인스턴스를 만들 때는 상속관계의 수퍼 클래스인 음료의 내용을 담는 공간에 콜라의 내용을 담는 공간이 추가되어 생성된다.
이렇게 만들어진 콜라 인스턴스는 음료 자료형 변수에 저장하면 음료의 기능만 사용하게 되고, 콜라 자료형 변수에 저장하면 콜라의 기능까지 모두 사용할 수 있다.
이때 콜라 인스턴스를 음료 변수에 담는 행위를 상위 자료형인 수퍼클래스로 변환한다고 하여 Up-Casting이라 하고,
Up-Casting 된 인스턴스를 다시 하위 자료형으로 변환하면 Down-Casting이라 부른다.
Up-Casting은 그냥 상위 자료형에 담는 것으로 동작하지만, Down-Casting은 별도로 as와 is라는 연산자가 필요하다.
as : 변수를 호환되는 자료형으로 변환해주는 캐스팅 연산자로, 사용 즉시 자료형을 변환해주며 변환된 자료형을 반환할 수도 있다.
is : 변수가 자료형에 호환되는지를 먼저 체크한 후 변환해주는 캐스팅 연산자로, 조건문 내에서 사용되는 특징이 있다.
fun main() {
var a = Drink()
a.drink()
var b: Drink = Cola()
b.drink()
//b.washDishes() 에러 발생!
}
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}으로 설거지를 합니다")
}
}
b는 Drink 타입의 변수이지만 Cola의 인스턴스를 담았으므로 Cola에서 override한 함수가 실행된다.
하지만 b는 Drink 변수이므로 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()
}
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}으로 설거지를 합니다")
}
}
b가 Cola와 호환되는지 is를 통해 여부를 확인하고 중괄호 안에서 b의 washDishes 함수를 호출해 보자.
is는 조건문 안에서만 잠시 다운캐스팅 된다는 점을 잊지 말자.
다음은 b as Cola 라는 구문으로 다운캐스팅 한 것을 변수 c에 할당하고 c에서 washDishes 함수를 호출해 보자.
둘 다 정상적으로 출력되는 것을 확인할 수 있다.
이때, main함수 마지막 라인에 b에서 washDishes 함수를 호출하는 구문을 넣으면 에러가 나지 않는다.
이는 as를 사용하면 반환값 뿐만 아니라 변수 자체도 다운캐스팅 되기 때문이다.
다형성은 클래스의 상속관계에서 오는 인스턴스의 호환성을 적극 활용할 수 있는 기능이다.
수퍼클래스가 같은 인스턴스를 한번에 관리하거나 인터페이스를 구현하여 사용하는 코드에서도 활용된다.
https://www.youtube.com/watch?v=q7GV68jKLVM&list=PLQdnHjXZyYadiw5aV3p6DwUdXV2bZuhlN&index=18
위 강의를 보면서 개인적으로 공부한 내용을 정리하였습니다.
'[Study] > Kotlin' 카테고리의 다른 글
[코틀린/Kotlin] 데이터를 담는 리스트 (0) | 2022.05.09 |
---|---|
[코틀린/Kotlin] 캐스팅을 줄여주는 제너릭 (0) | 2022.05.09 |
[코틀린/Kotlin] Object, Companion Object (0) | 2022.05.08 |
[코틀린/Kotlin] 람다함수의 특별한 케이스(it), 스코프 함수(apply, run, with, also, let) (0) | 2022.05.07 |
[코틀린/Kotlin] 고차함수와 람다함수 (0) | 2022.05.07 |