The Swift Programming Language - Inheritance（継承）をまとめる


[The Swift Programming Language をまとめるトップ](http://qiita.com/kiyotaman/items/052f82e9f93590b79c64)

## Inheritance（継承）
クラスはメソッドやプロパティを他のクラスから継承することができる
何かを継承しているクラスの事をサブクラスと言い継承されたクラスをスーパークラスと言う

クラスはすべてのメソッドやプロパティやサブスクリプトにアクセスでき、また、オーバライドもできる
他プロパティオブザーバーなども継承できたりする
保存型や算出プロパティ問わずオブザーバーは追加できる（以下で説明）

### Defining a Base Class（ベースクラスの定義）
何も継承していないクラスのことをベースクラスという

以下、 _Vehicle_ がベースクラスとして定義され、 _numberOfWheels_ と _maxPassngers_ がプロパティとして宣言されている
_description_ メソッドはプロパティの解説をしている

```swift
class Vehicle {
    var numberOfWheels: Int
    var maxPassengers: Int
    func description() -> String {
        return "\(numberOfWheels) ホイール; 上限乗車数\(maxPassengers)人"
    }
    init() {
        numberOfWheels = 0
        maxPassengers = 1
    }
}
```

_Veicle_ クラスはイニシャライザーを定義し初期値を設定している
サブクラスによってどのようにプロパティを設定するか紹介する必要がある

イニシャライザーはメソドッドのシンタックスとほぼ同等
インスタスのプロパティが正しい初期値をもっているかなど確実なものにするために必要

以下、引数無しが一番シンプルな書き方

```swift
init() {
	// ここに初期設定を書く
}
```

インスタンスの生成は以下の様になる

```swift
let someVehicle = Vehicle()
```


### Subclassing
クラスを継承してサブクラスでリファインする

以下が継承の方法で _:_ を使っ継承できる

```swift
class SomeClass: SomeSuperclass {
	// クラスの定義を書く
}
```

_Vehicle_ クラスの特徴を継承して新たに _Bicyle_ クラスを定義する

```swift
class Bicycle: Vehicle {
	init() {
		super.init()
		numberOfWheels = 2
	}
}
```

super.init() を呼び出し _Bicycle_ で値が修正される前に初期値を設定し、 _numberOfWheels_  のみ書き換える
自転車なので _maxPassengers_ は 1 のまま

> **NOTE**
ObjCとは異なりイニシャライザーはデフォルトで継承されない
詳細は [Initializer Inheritance and Overriding.](https://developer.apple.com/library/prerelease/ios/documentation/Swift/Conceptual/Swift_Programming_Language/Initialization.html#//apple_ref/doc/uid/TP40014097-CH18-XID_290)

_description_ メソッドも以下の様に継承されている

```swift
let bicycle = Bicycle()
println("自転車: \(bicycle.description())")
// prints "自転車: 2 ホイール; 上限乗車数 1 人
```

サブクラスもまた継承することができる

```swift
class Tandem: Bicycle {
	init() {
		super.init()
		maxPassengers = 2
    }
}
```

_maxPassengers_ のみアップデートしている

> **Note**
サブクラスは初期化中に変数のみ修正することができる
継承された定数はサブクラスで修正することができない

Tandem のインスタンをつくって、 _description_ を実行してみると上限乗車のみ更新されていることがわかる

```swift
let tandem = Tandem()
println("Tandem: \(tandem.description())")
// prints "Tandem: 2 ホイール; 上限乗車数 2 人
```

description() 最上位で定義されているメソッドも有効

### Overriding
オーバライディング（Overriding）はインスタンスメソッドやクラスメソッドやインスタンスプロパティやサブスクリプトの実装をサブクラスでカスタマイズすること

##### override
継承する対象の定義の頭に **override** を記述するとオバーライドする
override をつけないで同じ名前のものを定義しようとしたら同一のもがあると言うエラーがでる
何も記述しない場合は、スーパークラスのものがそのまま継承される

#### Accessing Superclass Methods, Properties, and Subscripts

##### super
オーバーライドしたメソッドやプロパティやサブスクリプトからスパークラスの実装をそのまま使いた時に **super** を使ってアクセスすることができる

* オーバーライドしたメッソドは オーバーライドしているメソッドを _super.someMethod()_ で呼び出す事ができる
* オーバーライドしたプロパティは、  オーバーライドしている getter, setter で _supper.someProperty_ を呼び出す事ができる
* オーバーライドしたサブスクリプトは、 オーバライドしているサブスクリプトの実装内で _supper[someIndex]_ を呼び出す事ができる

#### Overriding Methods（メソッドのオーバーライド）
新しく _Car_ サブクラスを _Veicle_ クラスを継承して　_description()_ をオーバーライドしているクラスを定義してみる

```swift
class Car: Vehicle {
    var speed: Double = 0.0
    init() {
        super.init()
        maxPassengers = 5
        numberOfWheels = 4
    }
    override func description() -> String {
        return super.description() + "; "
            + "\(speed) mph で移動中"
    }
}
```

Double で speed という保存型プロパティを宣言、初期値は 0.0
あと、イニシャライザーも定義して継承したプロパティの値を設定する
**override** プリフィックスを使って _description()_ をオーバライドする
super.descrioption をオーバライドしたメッソド内で呼び出して新たな実装をしている

If you create a new instance of Car, and print the output of its description method, you can see that the description has indeed changed:

```swift
let car = Car()
println("車: \(car.description())"
// prints "車: 4 ホイール; 上限乗車数 5 人 0.0 mph で移動中"
```

#### Overriding Properties（プロパティのオーバーライド）
保存型、算出型プロパティ問わず、 getter と setter を使ってオーバーライドを記述することができる
プロパティの型と名前を正しく指定する必要がある

_read-only_ プロパティをオーバライドして _read-write_ プロパティとして getter と setter を定義することはできる
その代わり、 _read-write_ プロパティは _read-only_ として定義することはできない

> **NOTE**
例えば継承した getter のプロパティーを変更したくない場合、そのまま super クラスのプロパティを以下の例の様に返すと良い

スピードの制限を設定したクラスを生成してみる

```swift
class SpeedLimitedCar: Car {
    override var speed: Double {
    get {
        return super.speed
    }
    set {
        super.speed = min(newValue, 40.0)
    }
    }
}
```

set 内で min を使って speed プロパティを調整する
min は引数のどちらかが小さい場合、小さい方を返すグローバル関数

```swift
let limitedCar = SpeedLimitedCar()
limitedCar.speed = 60.0
println("スピード上限: \(limitedCar.description())")
// prints "スピード上限: 4 ホイール; 上限乗車数 5 人 40.0 mph で移動中"
```

#### Overriding Property Observers（プロパティオブザーバーのオーバーライド）
プロパティオブザーバーもオバーライドすることができる

> **NOTE**
定数と read-only の算出プロパティは監視することができない
値を新たにセットすることができないので、監視する必要がない
オバーライドされている setter と プロパティオブザーバーも、そこで監視すればよいのでオブザーバを再定義することができない

オートマッティクの車クラス定義して値の変化を監視してみる

```swift
class AutomaticCar: Car {
    var gear = 1
    override var speed: Double {
    didSet {
        gear = Int(speed / 10.0) + 1
    }
    }
    override func description() -> String {
        return super.description() + " ギア \(gear)"
    }
}
```

didSet 内で 10.0 ごとに適切なギアを自動でセットしている

```swift
let automatic = AutomaticCar()
automatic.speed = 35.0
println("オートマ車: \(automatic.description())")
// prints "オートマ車: 4 ホイール; 上限乗車数 5 人 40.0 mph で移動中 ギア 4"
```

### Preventing Overrides（オーバーライドを防ぐ）

##### @final
@final class, @final var, $final func, @final class func, @final subscript と **@final** を付けてスーパークラス側で継承を防ぐこともできる
@final をオーバーライドしようとするとコンパイルエラーになる