정의
타입 캐스팅은 인스턴스의 타입을 확인 하는 "is"연산자와
해당 인스턴스를 수퍼 클래스 또는 하위 클래스로 취급하는 "as" 연산자가 있으며,
"as" 연산자는 사용 목적에 따라 업 캐스팅과 다운 캐스팅으로 나뉩니다.
is
타입 체크를 목적으로 사용하는 연산자입니다.
런타임 시점에서 구현되며, True와 False 값이 반환됩니다.
형식
표현식 is Type
예제1
let A: Int = 10
let B = A is String
let C = A is Int
print(B) // False
print(C) // True
예제2
또한, 상속에서 활용하는 경우
표현식에 대한 Type이 서브클래스인지, 특정 Type으로 캐스팅 되는지 체크하는 기능으로도 사용됩니다.
class Man { }
class Student: Man { }
let Minho: Student = .init()
let A = Minho is Student
let B = Minho is Man
print(A,B) // True True
as : Type Casting
표현식이 특정 Type으로 캐스팅된다면, 상속 관계에서 as키워드를 통해 업 캐스팅과, 다운 캐스팅을 할 수 있습니다.
또한, Any와 AnyObject 타입을 통해 상속 관계가 아니여도 예외적으로 캐스팅을 구현할 수 있습니다.
as 연산자의 종류
as | 컴파일 단계에서 캐스팅 : 업 캐스팅 기능 |
as? | 런타임 단계에서 캐스팅 : 다운 캐스팅 기능 |
as! | 런타임 단계에서 강제 캐스팅 : 다운 캐스팅 기능 |
업 캐스팅
정의
서브 클래스 인스턴스를 "수퍼 클래스의 타입"으로 참조합니다.
업 캐스팅은 항상 성공합니다.
예제
Man, Student, Major라는 3개의 클래스가 있고 Student, Major 클래스는 Man클래스를 상속받은 상태입니다.
Major 타입의 인스턴스를 생성해, 이를 Man타입으로 업 캐스팅해서 상수 A에 저장시켰습니다.
-
상수 A를 통해 수퍼 클래스인 Man 클래스의 멤버 name을 출력시켰을 땐, Minwoo라는 값이 오류없이 출력됩니다.
하지만, 똑같은 조건으로 상수 A를 통해 수퍼 클래스인 Man 클래스를
상속받는 Major클래스의 멤버 subject를 출력시켜 보면 Crash가 발생합니다.
-
예제를 통해 Man 클래스의 멤버인 name엔 접근이 가능하지만,
서브 클래스 Major의 멤버인 subject에는 접근 할 수 없다는 것을 알 수 있습니다.
즉, 업 캐스팅은 서브 클래스의 인스턴스를 수퍼 클래스의 타입으로만 참조할 수 있습니다.
class Man {
let name: String = "Minwoo"
}
class Student: Man {
let grade: Int = 2
}
class Major: Man{
let subject: String = "Swift"
}
let A = Major.init() as Man
print(A.name)
print(A.grade)
다운 캐스팅
정의
다운 캐스팅은 업 캐스팅의 반대 개념입니다.
수퍼 클래스에 대한 참조가 아닌, 하위 클래스에 대한 참조의 목적으로 사용됩니다.
느낌표(!)와 물음표(?)를 as 뒤에 붙여, 다운 캐스팅의 실패 확률이 있을 경우 as? 로 사용하고
실패확률이 없을 경우 as! 로 강제 캐스팅할 수 있습니다.
예제
이전과 동일한 예제입니다.
직전에는 Major 타입의 인스턴스를 Man 클래스로 업캐스팅하여 상수 A에 저장했습니다.
이번에는 Man 타입으로 업 캐스팅된 A를 다시 Major 클래스로 다운캐스팅해, 변수 B에 저장하겠습니다.
그리고 변수 B를 통해 Man 클래스의 멤버와 Major 클래스의 멤버를 출력해봤더니 모두 오류없이 출력됩니다.
-
이는 다운 캐스팅을 통해 서브클래스 즉, 하위 클래스의 멤버에 접근할 수 있게 된 것입니다.
class Man {
let name: String = "Minwoo"
}
class Student: Man {
let grade: Int = 2
}
class Major: Man{
let subject: String = "Swift"
}
let A = Major.init() as Man
print(A.name) // Minwoo
var B: Major = A as! Major
print(B.subject) // Swift
print(B.name) // Minwoo
마무리
as! 를 통해 다운캐스팅을 실패했을 때는 Crash가 발생하니 주의해야합니다.
as? 를 통해 다운캐스팅을 실패했을 때는 nil값이 반환되기 때문에
Optional Type으로 선언해 비교적으로 안전하게 접근할 수 있습니다.
내용출처
https://babbab2.tistory.com/127
https://www.youtube.com/watch?v=sIKESw-qa8k
'iOS > Swift 문법 심화 학습' 카테고리의 다른 글
값 타입과 참조 타입 (0) | 2022.01.31 |
---|---|
extensions (0) | 2022.01.30 |
guard (0) | 2022.01.28 |
assert (0) | 2022.01.28 |
Initializer (0) | 2022.01.27 |
댓글