예제
let rect = Rectangle()
rect.color
rect.cornerRadius
(rect as Shape).color // white 출력
(rect as Shape).cornerRadius // 오류발생 ; 타입이 shape으로 바뀌면서 cornerRadius가 없기 때문에
(rect as Rectangle).color // white 출력
(rect as Rectangle).cornerRadius // 0.0
let upcastedRect: Shape = Rectangle()
type(of: upcastedRect) //
upcastedRect.color // white ; 실제 인스턴스값을 반환함 (= 입력되는 값)
(upcastedRect as Rectangle).color // 오류 ; 부모클래스에서 자식클래스로 변환하는 것에 'as'사용 불가 ; 자식클래스는 부모클래스가 '하나'이지만 부모클래스는 여러개의 자식클래스를 가질 수 있기에 확실하게 변환될 타입을 찾지 못 할 수도 있음
예제
let shapeRect: Shape = Rectangle()
var downcastedRect = Rectangle()
downcastedRect: Rectangle = shapeRect as? Rectangle // 'shapeRect as? Rectangle'는 optional타입으로 바꾸는 것 -> 타입이 맞지 않아 오류 발생
// var downcastedRect: Rectangle? = Rectangle()로 바꾸면 가능함
@Int, Float Type Casting 해보기
let value = 1
(value as Float) is Float // Int와 Float은 관련 없는 타입이라 타입케스팅 안됨
(value as? Float) is Float // false -> 관련 없는 타입이라 nil 반환
(value as! Float) is Float // 런타임 오류 발생
@타입을 체크해 보자
let shape = Shape()
let rectangle = Rectangle()
let triangle = Triangle()
let list = [shape, rectangle, triangle]
for elem in list {
if elem is Shape {
print("shape instance")
} else if elem is Rectangle {
print("rect instance")
} else if elem is Triangle {
print("triangle instance")
}
}
=> for문 순서로 인해 shape instance만 출력 ; 순서를 조정하면 하나씩 출력됨