스위프트에서 타입캐스팅이란 인스턴스의 타입을 확인하거나 인스턴스를 superClass나 subClass로 취급하는 방법을 의미한다.
var someInt: Int=10;
var someDouble: Double = Double(someInt)
위코드는 Double타입의 init함수를 통해 만들어진 새로운 값에 불과하다. 타입캐스팅 이라고 볼 수 없다.
is키워드는 인스턴스가 현재 어떤타입인지 확인할 때 사용한다.
유의할 점은 인스턱스의 부모 클래스 역시 자신이 포함함으로 같은 타입으로 인식한다. 아래코드를 보자
class Person {
var name: String
var age: Int
init(name: String, age:Int){
self.name=name
self.age=age
}
}
//class는 하나의 상위 클래스만을 상속받을 수 있다..
class Student: Person {
var grade: Int;
init(name:String, age:Int, grade:Int){
self.grade=grade
super.init(name: name, age: age)
}
}
var someStudent = Student(name: "choi", age: 23, grade: 3)
//someStudent는 Person타입의 자식 인스턴스 임으로 결과는 true이다
print(someStudent is Person) //true
print(someStudent is Student) //true
as키워드는 특정 인스턴스를 다른 타입으로 치환하여 사용하고 싶을 때 사용한다.
자식타입을 부모타입으로 치환하는 다운캐스팅은 가능하지만 역순으로 할 경우 nil값을 반환한다.
//as? 키워드는 옵셔널 타입을 반환한다
if let person = someStudent as? Person {
print("I'm person")
}
var somePerson = Person(name: "hoon", age: 21)
//업캐스팅시 nil을 반환한다.
guard let someStu=somePerson as? Student else {
print("I'm not student")
fatalError()
}
옵셔널 강제추출처럼 다운캐스팅도 강제추출이 가능하다.
let person1 = someStudent as! Person
print(type(of: person1)) //Person
하지만 업캐스팅이 가능한 경우도 있다
class Brain {
func say(){
print("1")
}
}
class Person:Brain{
func good() {
print(2)
}
}
var var1:Brain = Person() as Brain
var var2:Person=var1 as! Person
var2.good() //2
한번 다운캐스팅된 타입을 다시 업캐스팅하는 것은 가능하다.
특이한 경우가 하나더 있다.
만약 다형성 구현을 한 관계에서 다운캐스팅을 할 경우 다운캐스팅 하였다 할지라도 override된 함수가 호출된다!!! amazing
class Brain {
func say(){
print(1)
}
}
class Person:Brain{
override func say() {
print(2)
}
}
var var1:Brain = Person() as Brain
var1.say() //2
as와 is는 상속뿐만아니라 해당 타입이 어떤 프로토콜을 가지는 지 확인할 때도 사용이 가능하다.
protocol SomeProtocol {
var name: String {get set}
}
class Person: SomeProtocol {
var name: String = "choi"
}
var person = Person()
print(person is SomeProtocol) //true
if let haveP = person as? SomeProtocol {
print("yes") //yes
}