[Swift 기초] 타입캐스팅
2022. 4. 4. 10:28ㆍSwift 기초 정리
728x90
//공부 기록용 포스팅입니다. 틀린 부분이 있을 경우 댓글로 알려주시면 감사합니다! 😎
- 타입캐스팅은 인스턴스의 타입을 확인하는 용도(is)
- 클래스의 인스턴스를 부모 혹은 자식 클래스의 타입으로 사용할 수 있는 지 확인하는 용도(as)
0. 참고
let someInt: Int = 100
let someDouble: Double = Double(someInt)
- 타입캐스팅이 아니라 → someInt라는 값을 가지고 Double 타입의 값을 하나 더 생성해주는 것
타입 캐스팅 예제를 위한 클래스 정의
class Person {
var name: String = ""
func breath(){
print("숨을 쉽니다.")
}
}
class Student: Person {
var school: String = ""
func goToSchool(){
print("학교를 갑니다.")
}
}
class UniversityStudent: Student{
var major: String = ""
func freeFriday(){
print("대학생은 금공강이지!")
}
}
//인스턴스 생성
var p: Person = Person()
var s: Student = Student()
var u: UniversityStudent = UniversityStudent()
1. 타입 확인 - is
//is를 사용해서 타입을 확인 - 연산의 결과는 true/false
var result: Bool
result = p is Person //true
result = p is Student //false
result = p is UniversityStudent //false
//Student는 Person 클래스를 상속받았기 때문에 Person의 특성을 가지고 있음
result = s is Person //true
result = s is Student //true
result = s is UniversityStudent //false
//UniversityStudent는 Student를 상속받고, Person도 상속받음
result = u is Person //true
result = u is Student //true
result = u is UniversityStudent //true
- is를 사용해서 타입을 확인할 수 있다. 연산의 결과는 true / false
- Type과 동일하거나 Type의 서브클래스 인 경우 true
- 그 외 false
- 상속에 유의해야 함
1-1. 타입확인 switch - case
- 상속과 관련된 클래스는 switch문의 순서에 주의해야 한다.
if p is UniversityStudent {
print("p는 대학생입니다.")
}else if p is Student{
print("p는 학생입니다.")
}else if p is Person{
print("p는 사람입니다.")
} //p는 사람입니다.
switch s{
case is Person:
print("s는 사람입니다.")
case is Student:
print("s는 학생입니다.")
case is UniversityStudent:
print("s는 대학생입니다.")
} //s는 사람입니다.
1-2. 타입 캐스팅 - as
- 변환할 type과 호환된다면 변환할 type으로 캐스팅된 인스턴스를 리턴한다.
2. 업 캐스팅 - as
- as를 사용하여 부모 클래스의 인스턴스로 사용할 수 있도록 컴파일러에게 타입정보를 전환
- 서브 클래스 → 슈퍼 클래스
- 하위 클래스(sub class)는 항상 상위 클래스의 부분집합 이므로 언제나 성공
- Any혹은 AnyObject로도 타입정보를 변환할 수 있다.
- 암시적으로 처리되기 때문에 생략해도 무방하다.
//Person 타입으로 선언했더라도 (실질적으로) UniversityStudent 타입으로 할당할 수 있다.//Person 타입으로 선언했더라도 UniversityStudent 타입으로 생성할 수 있다.
var p2: Person = UniversityStudent() as Person
var s2: Student = Student()
//어떤 타입도 가능하다.
var a: Any = Person() //as Any 암시적으로 생략 가능
- UniversityStudent 타입의 인스턴스 p2를 생성하지만, 이를 Person 타입으로 업캐스팅해서 p2에 저장하겠다.
3. 다운 캐스팅 - as? 또는 as!
- as? 또는 as! 를 사용하여 자식 클래스의 인스턴스로 사용할 수 있도록 컴파일러에게 인스턴스 타입 정보를 전환
- 슈퍼 클래스 → 서브 클래스
- 업케스팅을 한 변수만 다운케이스팅을 할 수 있는건가? 에 대한 야곰님의 답변
- 업 캐스팅 하여 저장(혹은 전달)된 인스턴스는 향후 다운 캐스팅에 성공할테고, 그렇지 않은 인스턴스는 다운 캐스팅 시도 때 실패하겠죠. as? 를 사용하면 성공 or 실패를 할 수 있고, as! 를 사용하면 성공때는 문제 없지만 실패하면 프로그램이 죽어버립니다. 다운캐스팅하려는 대상이 업 캐스팅 된 상태인지 항상 알 수는 없기 때문에 ! 는 사용을 지양하는게 좋겠죠.
3-1. 조건부 다운 캐스팅 - as?
- 런타임 시점에 타입 캐스팅을 하며, 실패할 경우 nil을 리턴
- 반환 타입이 옵셔널 타입
// p2는 실질적으로 할당된 인스턴스가 UniversityStudent이기 떄문에
// Person 타입으로 선언했어도 UniversityStudent로 다운 캐스팅 할 수 있다.
// 캐스팅에 성공할 경우 결과값은 옵셔널로 반환
optionalCasted = p2 as? UniversityStudent //Optional(Page_Contents.UniversityStudent)
// s2는 Student, a는 Person 이기 때문에 UniversityStudent로 다운 캐스팅할 수 없다
// 실패가능성을 내포하고 있기 때문에 nil이 반환될 수 있다.
optionalCasted = s2 as? UniversityStudent //nil
optionalCasted = a as? UniversityStudent //nil
optionalCasted = a as? Student //nil
3-2. 강제 다운 캐스팅 - as!
- 런타임 시점에 타입 캐스팅을 하며, 실패할 경우 런타임 오류 발생
- 반환 타입이 옵셔널이 아니라 일반 타입이라 편하게 사용할 수 있음
optionalCasted = p2 as! UniversityStudent
//s2는 Student, a는 Person 이기 때문에 UniversityStudent가 될 수 없다.
//런타임 오류 발생
//optionalCasted = s2 as! UniversityStudent
//optionalCasted = a as! UniversityStudent
//optionalCasted = a as! Student
3-3. 다운캐스팅 예제
//상위 클래스
class MediaItem {
var name: String
init(name: String) {
self.name = name
}
}
class Movie: MediaItem {
var director: String
init(name: String, director: String) {
self.director = director
super.init(name: name)
}
}
class Song: MediaItem {
var artist: String
init(name: String, artist: String) {
self.artist = artist
super.init(name: name)
}
}
let library = [
Movie(name: "Casablanca", director: "Michael Curtiz"),
Song(name: "Blue Suede Shoes", artist: "Elvis Presley"),
Movie(name: "Citizen Kane", director: "Orson Welles"),
Song(name: "The One And Only", artist: "Chesney Hawkes"),
Song(name: "Never Gonna Give You Up", artist: "Rick Astley")
]
//item을 하위 클래스로 다운캐스팅 해서 사용할 수 있다.
for item in library {
if let movie = item as? Movie {
print("Movie: \\(movie.name), dir. \\(movie.director)")
} else if let song = item as? Song {
print("Song: \\(song.name), by \\(song.artist)")
}
}
//Movie: Casablanca, dir. Michael Curtiz
//Song: Blue Suede Shoes, by Elvis Presley
//Movie: Citizen Kane, dir. Orson Welles
//Song: The One And Only, by Chesney Hawkes
//Song: Never Gonna Give You Up, by Rick Astley
참고하였습니다. 감사합니다.
https://yagom.net/courses/swift-basic/lessons/옵셔널-심화/topic/타입캐스팅/
728x90
'Swift 기초 정리' 카테고리의 다른 글
[Swift 기초] assert와 guard (0) | 2022.04.05 |
---|---|
[Swift 기초] 자동참조계수, 강한참조, 약한참조 (0) | 2022.04.04 |
[Swift 기초] 인스턴스의 생성과 소멸 (0) | 2022.04.02 |
[Swift 기초] 클래스와 상속 (0) | 2022.04.02 |
[Swift 기초] 프로퍼티 (0) | 2022.03.31 |