あるクラス型の定数や変数が、実際にはサブクラスのインスタンスを参照している場合があります。このケースでは、型キャスト演算子(as?
または as!
)でサブクラスの型にダウンキャストすることができます。
ダウンキャストは失敗することがあるため、型キャスト演算子には 2 種類の形式があります。条件形式の as?
は、ダウンキャストしようとする型のオプショナル値を返します。強制形式の as!
は、1 回のアクションとして結果をダウンキャストして強制アンラップします。
ダウンキャストが成功するか不確かなときは、条件形式の型キャスト演算子 (as?
) を使用します。この形式の演算子は常にオプショナル値を返し、ダウンキャストできなかった場合には値は nil
になります。これでダウンキャストが成功するかを確認することができます。
ダウンキャストが常に成功することが確かなときは、強制形式の型キャスト演算子 (as!
) を使用します。正しくないクラス型にダウンキャストしようとした場合には、この形式の演算子は実行時エラーを起こします。
次の例では、library
にある各 MediaItem
を繰り返し処理し、各アイテムの適切な説明を出力します。こうするには、MediaItem
としてでなく、Movie
や Song
として各アイテムにアクセスする必要があります。説明に使用するため、Movie
あるいは Song
の director
や artist
プロパティにアクセスできるようにする必要があります。
この例では、配列の各アイテムは Movie
または Song
になります。各アイテムの実際のクラスが事前にはわかっていないため、ループごとにダウンキャストをチェックするために、条件形式の型キャスト演算子 (as?
) を使用することが適切です。
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)")
}
}
// Movie: Casablanca, dir. Michael Curtiz
// Song: Blue Suede Shoes, by Elvis Presley
// Movie: Citizen Kane, dir. Orson Welles
// Song: The One And Only, by Chesney Hawkes
// Song: Never Gonna Give You Up, by Rick Astley
この例は Movie
として現在の item
をダウンキャストしようとすることから始まります。item
は MediaItem
インスタンスであるため、Movie
であるかもしれず、Song
であるかもしれず、あるいは単にベースの MediaItem
かもしれません。このように不確実であるため、サブクラス型にダウンキャストしようとするときに、型キャスト演算子の as?
はオプショナル値を返します。item as? Movie
の結果は、Movie?
、つまりオプショナル Movie
となります。
Movie
へのダウンキャストを、ライブラリ配列にある Song
インスタンスに適用しようとすると失敗します。これに対処するために、上の例ではオプショナルバインディングを使用して、オプショナル Movie
が実際に値を含んでいるかを(つまり、ダウンキャストが成功したかを調べるために)チェックしています。このオプショナルバインディングは if let movie = item as? Movie
で、次のように読むことができます。
「Movie
として item
にアクセスしてみる。成功する場合、オプショナル Movie
の値を一時的な定数 movie
に設定する。」
ダウンキャストが成功する場合、Movie
インスタンスの説明を出力するために、director
の名前を含め movie
のプロパティが使用されます。ライブラリに Song
が見つかったときには、Song
インスタンスのチェックと、(artist
名を含め)適切な説明を出力するために同じ法則が使用されます。
Portions of this page are translations based on work created and shared by Apple and used according to terms described in the Creative Commons Attribution 4.0 International License.