is
, as
연산자로 instance의 type을 check 하거나 cast 할 수 있다.
base class MediaItem
을 선언하고,
class MediaItem {
var name: String
init(name: String) {
self.name = name
}
}
MediaItem
class를 상속받는 subclass Movie
, Song
을 정의한다.
class Movie: MediaItem {
var director: String
init(name: String, director: String) {
self.director = director
super.init(name: name)
}
}
class Song: MediaItem {
var artist: String
init(name: String, artist: String) {
self.artist = artist
super.init(name: name)
}
}
상수 library
의 type은 Movie
와 Song
의 common superclass인 MediaItem
의 배열, [MediaItem]
으로 추론된다.
let library = [
Movie(name: "Casablanca", director: "Michael Curtiz"),
Song(name: "Blue Suede Shoes", artist: "Elvis Presley"),
Movie(name: "Citizen Kane", director: "Orson Welles"),
Song(name: "The One And Only", artist: "Chesney Hawkes"),
Song(name: "Never Gonna Give You Up", artist: "Rick Astley")
]
// the type of "library" is inferred to be [MediaItem]
library
의 item들이 [MediaItem]
타입으로 추론되기 때문에, 각 item의 native type으로 접근하려면 type check or downcast 해야한다.
type check 연산자인 is
를 사용하여 인스턴스가 특정 subclass 타입인지 check 할 수 있다.
for item in library {
if item is Movie {
movieCount += 1
} else if item is Song {
songCount += 1
}
}
downcast 연산자인 as?
or as!
를 사용해서 subclass 타입으로 다운캐스팅할 수 있다.
실제 class type이어야 멤버에 접근할 수 있기 때문에 조건문과 as?
연산자를 사용하여 다음 예제와 같이 downcast 할 수 있다.
for item in library {
if let movie = item as? Movie {
print("Movie: \(movie.name), dir. \(movie.director)")
} else if let song = item as? Song {
print("Song: \(song.name), by \(song.artist)")
}
}
as?
는 항상 optional type을 리턴하고, 다운캐스팅에 실패할 경우 nil
을 리턴한다.as!
는 다운캐스팅이 성공할 것을 확신하는 경우에 사용한다.Any
: function type을 포함해서 모든 인스턴스 타입이 될 수 있다.AnyObject
: 모든 class 인스턴스의 타입을 표현할 수 있다.https://docs.swift.org/swift-book/LanguageGuide/TypeCasting.html