公開中のアプリ

[Swift入門#24]クラス(型キャスト編)

今回は型キャストについて書きたいと思います。
型キャストの説明から実際の使用例までサンプルコードをもとにわかりやすく説明していきたいと思います。

型キャストとは?

簡単に説明するとクラスの型を変換する事を型キャストと言います。
最初は型を変換するってどう言う事?ってなると思いますがそのあたりも含めて説明します。
まずは例を見てみましょう。

事前準備

サンプルコードの確認

class Staff {
    let name: String
    init(_ name: String) {
        self.name = name
    }
}

class Staff2: Staff {
}

let mayugezio = Staff("まゆげじお")
let fuchan = Staff2("Fu-chan")
let dMatsuo = Staff2("D-Matsuo")

let staffs = [mayugezio, fuchan, dMatsuo] //型推論

for staff in staffs {
    if let s = staff as? Staff2 {
        print(s.name)
    }
}
//結果
//Fu-chan
//D-Matsuo

今回は「Staffクラス」とStaffクラスを継承した「Staff2クラス」を用意して、プロパティはわかりやすいように「nameプロパティ」だけにしてあります。
インスタンスは「mayugezio」、「fuchan」、「dMatsuo」の3人分作ってあります。
このサンプルをもとに書き方を説明していきます。

Swiftは継承したクラスと継承もとのクラスは同じ種類の型として認識してくれる。

これはどう言う事か下記コードで説明します。(サンプルコードでは15行目)

let staffs: [Staff] = [mayugezio, fuchan, dMatsuo]
let staffs = [mayugezio, fuchan, dMatsuo] //型推論

例えばスタッフを配列にまとめたい時があるとします。
上記コードのように、インスタンスしたスタッフを配列に格納してあげればOKだと思いますが、、、本当ならここでエラーになります。
なぜなら配列は同じ型じゃないと格納できないからです。
今回の場合「mayugezio」はStaffクラスで「fuchan」と「dMatsuo」はStaff2クラスなので違う型ですよね?

でも実際はここでエラーになりません。
そこはSwiftが優秀で、Staff2クラスはStaffクラスを継承しているので同じ種類の型として認識してくれるからです。

ちなみに2行目のように型推論で書く事も可能です。

型キャストの書き方

型キャストの書き方について説明したいと思います。

as?キーワード使って型キャストしてみよう。

では先ほどの配列staffsのStaff2クラスだけをループ処理したいと思います。
どうするかと言うとfor文でStaff2クラスだった時だけ、「nameプロパティ」をprint()で出力します。(サンプルコードでは17行目〜21行目)

for staff in staffs {
    if let s = staff as? Staff2 {
        print(s.name)
    }
}
//結果
//Fu-chan
//D-Matsuo

1行目ですが、ここで配列staffsをループさせて、staffに代入しています。
※for文に関しては[Swift入門#7]for文で繰り返し処理をしてみよう。を参考にしてみて下さい。

2行目でas?と言うキーワードを使いstaffをStaff2クラスに変換できるか試しています。
as?キーワードでは変換できなかった場合、nilが返ってくるのでOptional Bindingを使ってif let 定数名としています。
※Optional Bindingに関しては[Swift入門#12]オプショナル型を使ってみよう。を参考にしてみて下さい。

for文の流れとしては、
一周目 mayugezioがstaffに代入されます。しかし今回mayugezioはStaffクラスなので何も処理されず終わります。

二周目 fuchanがstaffに代入されます。fuchanはStaff2クラスなので2行目で型キャストされて3行目で出力されます。

三周目 dmatsuoもfuchanと同じ処理がされます。

結果 fuchanとdmatsuoの「nameプロパティ」が出力されます。

isとas!キーワードを使って型キャストしてみよう。

ここはおまけ的な感じですが、isとas!キーワードを使って型キャストしてみます。
下記コードで説明します。

for staff in staffs {
    if staff is Staff2 {
        let s = staff as! Staff2
        print(s.name)
    }
}

1行目のfor分は同じですね。
2行目ですが、as?の場合はOptional Bindingを使っていましたが、今回はisキーワードを使って、staffをStaff2クラスに変換できるか先に調べてあげます。
変換できる場合はif文の処理を実行します。
この処理ではもうstaffがStaff2クラスに変換できるとわかっているので、as?ではなくas!を使って強制的にアンラップしています。

まとめ

今回は型キャストについての記事を書きました。
慣れるまでは難しく感じるかもしれませんが、何度か使っていると理解できるようになると思います。
必要に応じて使っていきましょう!

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です

アプリ