스위프트의 타입캐스팅은 인스턴스의 타입을 확인하는 용도 또는 클래스의 인스턴스를 부모 혹은 자식 클래스의 타입으로 사용할 수 있는지 확인 하는 용도로 사용한다.
is, as 를 사용한다.
// 이것은 타입캐스팅이 아니다. someInt 를 받아서 새로운 인스턴스를 생성하는 것이다.
// 실제로 Double init 에 보면 타입별로 여러가지가 있는 것을 알 수 있다.
let someInt: Int = 100
let someDouble: Double = Double(someInt)
// 타입 캐스팅을 위한 클래스 정의
class Person {
var name: String = ""
func breath() {
print("숨을 쉽니다")
}
}
class Student: Person {
var school: String = ""
func goToSchool() {
print(" 등교를 합니다")
}
}
class UniversityStudent: Student {
var major: String = ""
func goToMT() {
print("멤버쉽 트레이닝을 갑니다")
}
}
var joy: Person = Person()
var hana: Student = Student()
var jason: UniversityStudent = UniversityStudent()
// is 사용
joy is Person // true
joy is Student // false
joy is UniversityStudent // false
hana is Person // true
hana is Student // true
hana is UniversityStudent // false
jason is Person // true
jason is Student // true
jason is UniversityStudent // true
// 업 캐스팅
// as를 사용하여 부모클래스의 인스턴스로 사용할 수 있도록
// 컴파일러에게 타입정보를 전환해 준다.
// Any 혹은 AnyObject 로도 타입정보를 변환할 수 있다.
// 암시적으로 처리되므로 생략해도 무방하다.
var mike: Person = UniversityStudent() as Person
var jenny: Student = Student()
// var jina: UniversityStudent = Person() as UniversityStudent // 컴파일 오류 발생
var jina: Any = Person() // as Any 생략 가능
// 다운 캐스팅
// as? 또는 as! 를 사용하여
// 자식 클래스의 인스턴스로 사용할 수 있도록
// 컴파일러에게 인스턴스의 타입정보를 전환해 준다.
// 조건부 다운 캐스팅 - 반환 타입 옵셔널임
// as?
var optionalCasted: Student?
// mike는 원래 UniversityStudent 인스턴스를 person 으로 업 캐스팅 한거기 때문에 가능하고 나머지는 불가능하다.
optionalCasted = mike as? UniversityStudent
optionalCasted = jenny as? UniversityStudent // nil
optionalCasted = jina as? UniversityStudent // nil
optionalCasted = jina as? Student // nil
// 강제 다운 캐스팅 - 반환 타입이 옵셔널이 아님
// as!
var forcedCasted: Student
optionalCasted = mike as! UniversityStudent
// optionalCasted = jenny as! UniversityStudent // 런타임 오류
// optionalCasted = jina as! UniversityStudent // 런타임 오류
// optionalCasted = jina as! Student // 런타임 오류
// 활용
func doSomethingWithSwitch(someone: Person) {
switch someone {
case is UniversityStudent:
(someone as! UniversityStudent).goToMT()
case is Student:
(someone as! Student).goToSchool()
case is Person:
(someone as! Person).breath()
}
}
doSomethingWithSwitch(someone: mike as Person)
// 멤버쉽 트레이닝을 갑니다
doSomethingWithSwitch(someone: mike)
// 멤버쉽 트레이닝을 갑니다
doSomethingWithSwitch(someone: jenny)
// 등교를 합니다
func doSomething(someone: Person) {
if let universityStudent = someone as? UniversityStudent {
universityStudent.goToMT()
} else if let student = someone as? Student {
student.goToSchool()
} else if let person = someone as? Person {
person.breath()
}
}
doSomething(someone: mike as Person)
// 멤버쉽 트레이닝을 갑니다
doSomething(someone: mike)
// 멤버쉽 트레이닝을 갑니다
doSomething(someone: jenny)
// 등교를 합니다
doSomething(someone: joy)
// 숨을 쉽니다
'# 02 > Swift' 카테고리의 다른 글
[Swift] 프로토콜 (0) | 2020.06.05 |
---|---|
[Swift] assert와 guard (0) | 2020.06.05 |
[Swift] 옵셔널 체이닝과 nil 병합 연산자 (0) | 2020.06.04 |
[Swift] 인스턴스의 생성과 소멸 (0) | 2020.06.04 |
[Swift] 상속 (0) | 2020.06.04 |