is
let char: Character = "A"
print(char is Character)
// 출력값: true
print(char is String)
// 출력값: false
let bool: Bool = true
print(bool is Bool)
// 출력값: true
print(bool is Character)
// 출력값: false
as
, as?
, as!
as
: 업캐스팅, 자식 타입으로 지정되어 있는 것을 부모 타입으로 끌어올린다.
class Person {
var id = 0
var name = "name"
var email = "hgk@gmail.com"
}
class Worker: Person {
// id
// name
// email
var salary = 300
}
class Programmer: Worker {
// id
// name
// email
// salary
var lang = "Swift"
}
// 업캐스팅 - as
let person = Person()
let worker = Worker()
let programmer1 = Programmer()
let personList = [person, worker, programmer1]
personList[1].name
//업 캐스팅
//배열의 타입을 명시하지 않으면 Swift는 배열의 요소를 가장 큰 공통의 타입으로 추론한다.
//Person 클래스가 가장 상위 클래스이기 때문에 배열의 요소를 Person 클래스로 추론한다.
//personList[1].salary // Person 타입으로 보고 있기 때문에 salary에 접근하지 못함
as?
: 다운캐스팅, 부모 타입으로 지정되어 있는 것을 자식 타입으로 내린다. 성공 시 옵셔널 타입의 인스턴스 반환, 실패하면 nil 반환
class Person {
var id = 0
var name = "name"
var email = "hgk@gmail.com"
}
class Worker: Person {
// id
// name
// email
var salary = 300
}
class Programmer: Worker {
// id
// name
// email
// salary
var lang = "Swift"
let person = Person()
let worker = Worker()
let programmer1 = Programmer()
//다운 캐스팅1
let pro = programmer as? Programmer
pro?.lang
if let person2 = programmer as? Programmer {
person2.lang
}
//같은 클래스의 인스턴스끼리는 같은 클래스로 다운캐스팅 가능
//progammer1은 Programmer 클래스 인스턴스이기 때문에 Programmer 클래스로 다운 캐스팅 가능
//그리고 이 경우는 "항상 성공"
//let: 다운 캐스팅 시도 -> 결과를 옵셔널 값으로 처리
//if let: 다운 캐스팅 시도 -> 성공 시에만 코드 처리
//다운 캐스팅2
if let person3 = worker as? Programmer {
print("다운캐스팅 성공")
} else {
print("다운캐스팅 실패")
}
//출력 "다운캐스팅 실패"
//다운 캐스팅이 되지 않는 이유?
//Programmer 클래스의 인스턴스가 Worker 클래스의 "모든 속성과 메서드"를 상속 받은 것은 맞지만,
//Worker 클래스의 인스턴스가 Programmer 클래스의 인스턴스가 되는 것은 아니다.
//클래스의 속성과 메서드를 상속 받는 것과, 인스턴스는 별개의 개념
//다운 캐스팅2가 성공하려면?
if let person3 = worker as? Programmer {
print("다운캐스팅 성공")
} else {
print("다운캐스팅 실패")
}
//출력 "다운캐스팅 성공"
//실행은 되는데 이런 주의문이 뜬다.
//항상 성공하는 캐스팅이라고 안내해준다.
//왜일까? 밑에 이어서 설명!
Conditional cast from 'Programmer' to 'Programmer' always succeeds
//1
let person = Person()
let worker = Worker()
let programmer1 = Programmer()
if let person3 = programmer as? Programmer {
print("다운캐스팅 성공")
} else {
print("다운캐스팅 실패")
}
/*
1에서는 programmer1에 타입을 따로 지정해주지 않았다.
따라서 programmer1의 타입은 타입 추론에 의해 "Programmer 타입"으로 지정이 된다.
if let에서 사용된 programmer1의 타입과 Programmer의 타입이 동일하기 때문에
항상 성공할 수 밖에 없는 캐스팅이라고 안내해준 것이다!
*/
//그렇다면 이러한 안내창이 뜨지 않는 경우는 뭘까?
//2에서 살펴보자
//2
let person: Person = Worker()
let worker: Person = Worker()
let programmer: Worker = Programmer()
if let person3 = programmer as? Programmer {
print("다운캐스팅 성공")
} else {
print("다운캐스팅 실패")
}
/*
2에서는 programmer의 타입을 Worker로 지정해주었다. (Type Annotation)
따라서 if let에서 사용된 programmer의 타입과 Programmer의 타입(Programmer)이 동일하지 않기 때문에
1에서 떴던 경고창이 뜨지 않는다!
*/
as!
: 다운캐스팅, 부모 타입으로 지정되어 있는 것을 자식 타입으로 내린다. 강제 타입 캐스팅, 성공하면 인스턴스 반환, 실패하면 런타임 에러
let pro2 = worker2 as! Programmer // Error : 타입 변환 실패시 오류
이야기 나눴던 내용 잘 정리해주셔서 다시 한 번 복습했어요 감사해용!