SHOEISHA iD

※旧SEメンバーシップ会員の方は、同じ登録情報(メールアドレス&パスワード)でログインいただけます

DeveloperZine(デベロッパージン)- エンジニアの意思決定を支える技術情報メディア ProductZine

CodeZine編集部では、現場で活躍するデベロッパーをスターにするためのカンファレンス「Developers Summit」や、エンジニアの生きざまをブーストするためのイベント「Developers Boost」など、さまざまなカンファレンスを企画・運営しています。

アップルの新プログラミング言語「Swift」を探検しよう

Swiftの「クラス」と「ストラクチャ」 その① ~ プロパティ、メソッド、継承、ライフサイクル

アップルの新プログラミング言語「Swift」を探検しよう 第4回


継承

 Swiftのクラスは、Objective-Cと同じような方法で継承を行うことが可能です。継承元となるスーパークラスの名前を、宣言するサブクラス名の後ろに「:」(コロン)に続けて記します。

class SomeSuper {
    var index: Int = 1
}
class SomeSub : SomeSuper {
    var name: String = "default"
}

 他の特徴もさることながら、Swiftのクラスは宣言時に基底クラス(JavaでいうところのObjectクラス)を継承せずに、それぞれが基底クラスとして宣言されるという特徴を持っています。インスタンスの同値性や、Stringに変換してのログ出力などは、基底クラスのメソッドを継承するのではなく、同値性の特徴を持ったプロトコル(Equatable)やStringに変換するためのプロトコル(Printable)に準拠させることによって行います。

 なお、ストラクチャは継承機能を持っていませんが、プロトコルに準拠させることが可能です。

 つまり、Objective-Cでは、isEqualやhash、descriptionといったNSObjectクラスに宣言されたメソッドをオーバーライドすることで同値性の判定などを実装しましたが、Swiftでは、これらの機能の実装一つ一つをプロトコルで行えるということです。こちらは次回以降のプロトコルを取り上げる回で解説します。

overrideキーワード

 Objective-Cでは、サブクラスを見ただけではスーパークラスからオーバーライドしたメソッドかどうか分かりませんでした。Swiftでは、オーバーライドしたメソッドにはoverrideキーワードを付ける必要があり、意図しないオーバーライドを防ぐことができるようになりました。

 次の例は、先ほどのSomeSuperクラスにprintInfo()というメソッドを用意して、SomeSubクラスでオーバーライドさせています。

class SomeSuper {
    var index: Int = 1
    func printInfo() {
        println("index : \(index)")
    }
}
class SomeSub : SomeSuper {
    var name: String = "name"
    override func printInfo() {
        super.printInfo()
        println("name : \(name)")
    }
}
let superVal = SomeSuper()
superVal.printInfo() // index : 1
let subVal = SomeSub()
subVal.printInfo() // index : 1  name : name

 なお、この例ではsuperキーワード経由で継承元クラスのメソッドを呼び出しています。この挙動は、Objective-Cから変化がありません。

 プロパティに関しても、サブクラスでget/set/willSet/didSetの挙動を変えたいときには、overrideキーワードをメソッド宣言と同様に付けることでオーバーライドができます。

final属性

 Objective-Cでサブクラス化を禁止する場合、イニシャライザでの動作時型検査で例外を投げるなどの方法がありました。Swiftでは、継承したクラスでオーバーライドさせたくない(禁止したい)プロパティやメソッドにはfinal修飾子を付けます。final修飾子が付けられたメソッドをオーバーライドしようとすると、コンパイル時にエラーが出力されます。

class SomeSuper {
    var index: Int = 1
    final var name: String {
        return "index : \(index)"
    }
}
class SomeSub : SomeSuper {
    override var name: String { // コンパイル時のエラー
        return "some string"
    }
}

 この仕組みにより、クラスの使用者に向けて、継承禁止の意図をより明確に伝えることが可能になりました。また、クラスそのものを継承させたくない場合は、classキーワードの前に修飾子を付けることで継承を禁止できます。

次のページ
ライフサイクルの管理

この記事は参考になりましたか?

アップルの新プログラミング言語「Swift」を探検しよう連載記事一覧

もっと読む

この記事の著者

yad(ヤド)

クラスメソッド株式会社のアプリケーションエンジニア。iPhoneアプリケーションの開発に2年以上従事している。開発に使用するObjective-Cのみならず、関数型言語Haskellや機械学習などにも関心がある。「Developers.IO」に寄稿した記事の一覧

※プロフィールは、執筆時点、または直近の記事の寄稿時点での内容です

この記事は参考になりましたか?

この記事をシェア

CodeZine(コードジン)
https://codezine.jp/article/detail/7898 2014/08/09 21:40

イベント

CodeZine編集部では、現場で活躍するデベロッパーをスターにするためのカンファレンス「Developers Summit」や、エンジニアの生きざまをブーストするためのイベント「Developers Boost」など、さまざまなカンファレンスを企画・運営しています。

新規会員登録無料のご案内

  • ・全ての過去記事が閲覧できます
  • ・会員限定メルマガを受信できます

メールバックナンバー