Coding Memo
Kotlin 캐스팅 본문
클래스 간 캐스팅은 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()
}
'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 |