swift 기초 - 옵셔널 체이닝, 타입캐스팅
[1] 옵셔널 체이닝
[1-1] 옵셔널 체이닝
옵셔널 체이닝은 옵셔널 요소 내부의 프로퍼티로
또다시 옵셔널이 연속적으로 연결되는 경우 유용하게 사용할 수 있다.
[1-2] 예제 클래스 및 인스턴스 생성
//사람 클래스
class Person {
var name : String
var job:String? // 직업 - 옵셔널
var home: Apartment? //집 - 옵셔널
//이름 초기화 메소드
init(name:String) {
self.name = name
}
}
//아파트 클래스
class Apartment {
var buildingNumber : String //동
var roomNumber: String //호수
var guardMan : Person? //경비원 - 옵셔널
var owner : Person? //주인 - 옵셔널
//초기화 메소드 : 동, 호수
init(dong:String , ho:String) {
buildingNumber = dong
roomNumber = ho
}
}
let kim :Person? = Person(name: "kimdongsu")
let apartment : Apartment? = Apartment(dong: "18", ho: "610")
let superman : Person? = Person(name: "superman")
옵셔널 체이닝이 실행 후 결과 값이 nil 일 수 있으므로
결과 타입도 옵셔널이다.
우리집 경비원의 직업은?
[1-3] 옵셔널 사용하지 않는 예제
func guardJob(owner:Person?) {
if let owner = owner{
if let home = owner.home {
if let guardman = home.guardMan {
if let guardmanJob = guardman.job{
print("우리집 경비원의 직업은 \(guardmanJob) 입니다.")
}else{
print("우리집 경비원은 직업이 없어요")
}
}
}
}
}
//호출
guardJob(owner: kim)
[1-4] 옵셔널 사용하는 예제
func guardJobWithOptionalChaining(owner:Person?) {
if let guardJob = owner?.home?.guardMan?.job{
print("우리집 경비원의 직업은 \(guardJob) 입니다.")
}else{
print("우리집 경비원은 직업이 없어요")
}
}
//호출
guardJobWithOptionalChaining(owner: kim)
출력
print(kim?.home?.guardMan?.job) //nil
//집 할당
kim?.home = apartment
print(kim?.home) //Optional(test2.Apartment)
print(kim?.home?.guardMan) //nil
//경비원 할당
kim?.home?.guardMan = superman
print(kim?.home?.guardMan) //Optional(test2.Person)
print(kim?.home?.guardMan?.name) //Optional("superman")
print(kim?.home?.guardMan?.job) //nil
//경비원 직업 할당.
kim?.home?.guardMan?.job = "슈퍼경비원!"
[2] 타입 캐스팅
스위프트의 타입캐스팅은 인스턴스의 타입을 확인하는 용도
또는 클래스의 인스턴스를 부모 혹은 자식 클래스 타입으로 사용할 수 있는지 확인하는 용도로 사용한다.
is, as 를 사용한다.
[2-1] 타입 캐스팅을 위한 클래스 정의
//슈퍼 클래스
class PersonA {
var name: String = ""
func breath() {
print("숨을쉬어요")
}
}
//서브 클래스 - 1
class Student: PersonA {
var school : String = ""
func gotoSchool() {
print("등교를 합니다..")
}
}
//서브 클래스 - 2
class UniversityStudent: Student {
var major : String = ""
func gotoMT(){
print("엠티를 갑니다~")
}
}
//인스턴스 객체 생성
var dongsoo : PersonA = PersonA()
var minwoo : Student = Student()
var jassy : UniversityStudent = UniversityStudent()
[2-2] 타입 확인 - is 를 사용해서 타입을 확인
var result : Bool
result = dongsoo is PersonA //true
result = dongsoo is Student //false : dongsoo 객체는 Student 클래스의 슈퍼 클래스이다.
result = dongsoo is UniversityStudent //false dongsoo 객체는 Student 클래스의 슈퍼 슈퍼 클래스이다.
result = minwoo is PersonA //true
result = minwoo is Student //true
result = minwoo is UniversityStudent //false : minwoo 객체는 UniversityStudent 클래스의 슈퍼 클래스이다.
result = jassy is PersonA //ture
result = jassy is Student //true
result = jassy is UniversityStudent //true
//dongsoo 객체의 타입 구하기
//dongsoo 는 PersonA 타입이다.
if dongsoo is UniversityStudent {
print("동수는 대학생입니다.")
}else if dongsoo is Student{
print("동수는 학생입니다.")
}else if dongsoo is PersonA{
print("동수는 사람입니다.") //동수는 사람입니다.
}
//jassy 객체의 타입 구하기
switch jassy{
case is PersonA :
print("jassy는 사람입니다.")
case is Student :
print("jassy는 학생입니다.")
case is UniversityStudent :
print("jassy는 대학원 생입니다.") //jassy는 사람입니다.
}
switch jassy {
case is UniversityStudent:
print("jassy은 대학생입니다")
case is Student:
print("jassy은 학생입니다")
case is PersonA:
print("jassy은 사람입니다")
default:
print("jassy은 사람도, 학생도, 대학생도 아닙니다")
} // jassy은 대학생입니다
[2-3] 업캐스팅
as 를 사용하여 부모 클래스의 인스턴스로 사용할 수 있도록
컴파일러에게 타입정보를 전환해준다.
Any 혹은 AnyObject로도 타입정보를 변환할 수 있다
암시적으로 처리되므로 생략해도 무방하다.
var mike : PersonA = UniversityStudent() as PersonA
var jenny : Student = Student()
var jina : Any = PersonA() // as Any 생략가능
print(mike) //test2.UniversityStudent
print(jenny) //test2.Student
print(jina) //test2.PersonA
[2-4] 다운캐스팅
as? 또는 as! 를 사용하여 자식 클래스의 인스턴스로 사용할 수 있도록
컴파일러에게 인스턴스의 타입정보를 전환해준다.
// as? 조건부 다운 캐스팅
var optionCasted:Student?
optionCasted = mike as? UniversityStudent //메모리 주소
optionCasted = jenny as? UniversityStudent //nil
optionCasted = jina as? UniversityStudent //nil
optionCasted = jina as? Student //nil
//as! 강제 다운캐스팅
var forcedCasted: Student
forcedCasted = mike as! UniversityStudent
//forcedCasted = jenny as! UniversityStudent //런타임 오류
//forcedCasted = jina as! UniversityStudent //런타임오류
//forcedCasted = jina as! Student //런타임오류
[2-5] 강제 다운 캐스팅 활용
func doSomethingWithSwitch(someone:PersonA) {
switch someone {
case is UniversityStudent:
//강제 다운캐스팅
(someone as! UniversityStudent).gotoMT()
case is Student:
(someone as! Student).gotoSchool()
case is PersonA:
(someone as! PersonA).breath()
}
}
doSomethingWithSwitch(someone: mike as PersonA) //엠티를 갑니다~
doSomethingWithSwitch(someone: mike) //엠티를 갑니다~
doSomethingWithSwitch(someone: jenny) //등교를 합니다..
doSomethingWithSwitch(someone: dongsoo) //숨을쉬어요
[2-6] 조건부 다운캐스팅 예제 함수
func doSomething(someone:PersonA) {
if let universityStudent = someone as? UniversityStudent {
universityStudent.gotoMT()
}else if let student = someone as? Student {
student.gotoSchool()
}else if let person = someone as? PersonA{
person.breath()
}
}
doSomething(someone: mike as PersonA) // 엠티를 갑니다~
doSomething(someone: mike) // 엠티를 갑니다~
doSomething(someone: jenny) // 등교를 합니다..
doSomething(someone: dongsoo) // 숨을쉬어요
참고
'아이폰 개발 > Swift' 카테고리의 다른 글
[스탠포드]Swift 강좌 - ios 구조 (0) | 2021.03.09 |
---|---|
swift 기초 - assert , guard , protocol (1) | 2021.03.05 |
swift 기초 - 상속, 인스턴스의 생성과 소멸 (0) | 2021.03.04 |
swift 기초 - 클로저 , 프로퍼티, 프로퍼티 감시자 (0) | 2021.03.04 |
swift 기초 - 옵셔널, 구조체, 클래스, 열거형, 값타입 참조타입 (0) | 2021.03.03 |