The Swift Programming Language - Classes and Structures（クラスと構造体）をまとめる


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

## Classes and Structures（クラスと構造体）
クラスにはプロパティ、メソッドを組み込む事ができる

クラスや構造体をつくる時、インターフェースや実装コードを含むファイルを必要としない
ファイルを分割しないでよくて、クラスや構造体は一つのファイルに書くことができる
外部から参照できるインターフェース自動的に使えるようになる

**クラスと構造体の共通点**

* 値を保持する事ができるプロパティの定義ができる
* メソッドを定義して機能を提供できる
* 添字を定義してそれらの値にアクセスできる
* イニシャライザーを定義してその中で初期設定ができる
* 実装を継承して機能性を高めることができる
* プロトコルに従って基本的な機能を提供することができる

詳細は Properties, Methods, Subscripts, Initialization, Extensions, and Protocols にて

**クラスのみにある特徴**
継承ができる
型のキャスティングができる
ランタイム中に型の解釈ができる
破棄してリソースをフリーにする事ができる
リファレンスをカウントすることで、複数のリファレンスで同一クラスを利用できる

詳細は Inheritance, Type Casting, Initialization, and Automatic Reference Counting にて

> **Note**
構造体を定義する時は、毎回複写される

### Definition Syntax（定義の方法）

```{}``` を使ってクラスも構造体も同じ様に定義できる

```swift

    class SomeClass {
    // class の定義
    }
    struct SomeStructure {
    // structure の定義
    }
```

> **Note**
クラスや構造体を定義する時は、新しくSwiftの型を指定する事なので、必ず最初の文字を大文字にする
最初の文字をプロパティやメソッドは小文字にする

ストラクチャとクラスの定義のサンプル

```swift
struct Resolution {
    var width = 0
    var height = 0
}

class VideoMode {
    var resolution = Resolution()
    var interlaced = false
    var frameRate = 0.0
    var name: String?
}
```

まず、 _Resolution_ という構造体を定義している
ピクセルベースのディスプレイの解像度をあらわしている
_width_ と _height_ ２つの _プロパティ_ を保持している
プロパティには定数（let）や変数（var）を宣言でき、クラスや構造体にまとめることができる
今回は値が変わる場合があるので変数を宣言する
そして、0を代入する
事の時、推論で _Int_ 型で定義される

次に、 _VideMode_ がクラスとして定義されている
ビデオのディスプレイモードをあらわしている
このクラスは解像度、インターレース、フレームレート、名前４つの値を定義したプロパティを保持している
どれも、型を推論してる
_new VideoMode_ をすることで、name 以外は初期値でイニシャライズされる
name は String? オプショナルで定義されているので、nil が自動でセットされる

### Class and Structure Instances（クラスと構造体のインスタンス）
インスタンスを以下のように定義する

```swift
let someResolution = Resolution()
let someVideoMode = VideoMode()
```

引数の指定がない空の括弧()を名前の後に続けて書いてインスタンスを初期化する

### Accessing Properties（プロパティアクセス）

プロパティには```.```ドットシンタックスで接続できる

```swift
println("someResolution の幅は \(someResolution.width)")
// prints "someResolution の幅は 0"
```

この例だと、someResolution.width は someResolution のプロパティを参照して初期値の 0 を返す

_VideMode_ のプロパティに設定された _resolution_ 経由でサブプロパティとしてアクセスする事もできる

```swift
println("someVideoMode の幅は \(someVideoMode.resolution.width)")
// prints "someVideoMode の幅は 0"
```

新しい値の代入もできる


```swift
someVideoMode.resolution.width = 1280
println("someVideoMode の幅は \(someVideoMode.resolution.width)")
// prints "someVideoMode の幅は 1280"
```

### Memberwise Initializers for Structure Types（構造体のメンバープロパティごとの代入と初期化）
あらゆる構造体は、新しい構造体のインスタンスとして、自動でメンバープロパティを初期化する

プロパティの名前を指定して初期化するときに値をしていすることができる

```swift
let vga = Resolution(width: 640, height: 480)
```

クラスは構造体と違って上記の様に初期値を受け取る事ができない

### Structures and Enumerations Are Value Types（構造体と列挙型(enum)値型）
値の型は変数や定数が代入された時か引数として渡されたときに複写される
全ての基本の型は構造体として存在している

全ての構造体や列挙型(enum)は値の型であり、つまり、全ての構造体や列挙型(enum)のインスタンスを生成するときには、そのプロパティは複写されるしくみになっている

以下の例をみてみる
_Resultion_ 構造対は上記の例の続き

```swift
let hd = Resolution(width: 1920, height: 1080)
var cinema = hd
```

_hd_ を定数として宣言して _Resultion_ インスタンスを新しい値 widht:1920 height:1080 をもって定義

次に、 _cinema_ を変数として _hd_ で定義、_cinmea_ は _hd_ のコピーとしてつくられる
_cinema_ と _hd_ のプロパティの値は同じだが、全く異なるインスタンス

次に、2048 を _cinema_ の幅に指定してみる

```swift
cinema.width = 2048
```

それぞれのプロパティの値を覗いてみる


```swift
println("cinema is now \(cinema.width) pixels wide")
// prints "cinema is now 2048 pixels wide"

println("hd is still \(hd.width) pixels wide")
// prints "hd is still 1920 pixels wide"
```

hd のプロパティと cinema のプロパティの width が違う事がわかる

enum 型も同じ動作をする

```swift
enum CompassPoint {
    case North, South, East, West
}
var currentDirection = CompassPoint.West
let rememberedDirection = currentDirection
currentDirection = .East
if rememberedDirection == .West {
	println("The remembered direction is still .West")
}
// prints "The remembered direction is still .West"
```

### Classes Are Reference Types（クラスは参照型）
クラスは構造体やenumとは違い、リファレンスを返す

videoMode を使ってみる例をみてみる

```swift
let tenEighty = VideoMode()
tenEighty.resolution = hd
tenEighty.interlaced = true
tenEighty.name = "1080i"
tenEighty.frameRate = 25.0
```

定数で _tenEighty_ という名前で VideoModeクラスのインスタンスを宣言し定義をしている

次に、_tenEnghty_ を使って定数 _alsoTenEight_ を新しく定義して、frameFrame を編集してみる

```swift
let alsoTenEighty = tenEighty
alsoTenEighty.frameRate = 30.0
```

tenEighty と alsoTenEighty は同じものを参照しているので、tenEighty の tenEighty も同時に変わる 

```swift
println("The frameRate property of tenEighty is now \(tenEighty.frameRate)")
// prints "The frameRate property of tenEighty is now 30.0"
```

> **Note**
定数で宣言してもプロパティの値を変更することができる実際に変更しているのはクラス内のメンバープロパティで、インスタンス自体は更新している値はその定数のリファレンスではない

### Identity Operators（同一演算）
同じインスタンスを参照しているか確認することができる

* 同一の場合 (===)
* 同一で無い場合 (!==)

```swift
if tenEighty === alsoTenEighty {
    println("tenEighty and alsoTenEighty refer to the same Resolution instance.")
}
// prints "tenEighty and alsoTenEighty refer to the same Resolution instance."
````

> **NOTE**
同等（==)の場合は値を比較するのとは違う
あくまでも、同じインスタンスを参照しているかをを確認する時に用いる


### Pointers（ポインター）
ポインターはメモリー上のアドレスを参照する
C言語のポインターと似た感じで定数と変数は振る舞うが、直接のポインターではなない。
(*)アスタリスクを使わないでリファレンスをつくる事ができる
Swift では定数と変数としてリファレンスが定義される


### Choosing Between Classes and Structures（クラスか構造体か？）
データタイプを定義する時にクラスと構造体両方使える
構造体は値を返し、インスタンスはリファレンスを返し使い分けが必要

**構造体を選ぶ場合の一般的なルール**

* 基本的な目的はお互い関係の単純なデータ値をまとめるためのもの
* まとまった値が複写される事を期待される理由があるとき
* 複写が期待されている構造体が保持されているプロパティ 
* 他の現存す型の動作やプロフパティを継承する必要がない

上記以外は、class を使うほうがよい
データモデルはクラスをつかったほうがよい

### Assignment and Copy Behavior for Collection Types（コレクション型の複写について）
Array と Dictionary はクラスとして実装されているので、コピーされない
リファレンスが渡される

### Assignment and Copy Behavior for Dictionaries（連想配列の複写について）
関数やメソッドの引数として渡された時は、値が複写される
また、変数タイプで宣言されたときもコピーされる

```swift
var ages = ["Peter": 23, "Wei": 35, "Anish": 65, "Katya": 19]
var copiedAges = ages
copiedAges["Peter"] = 24
println(ages["Peter"])
// prints "23"
```

もとの値と更新した値が異なる

### Assignment and Copy Behavior for Arrays（配列の複写について）
配列もコピーじゃなくて同じ配列の要素を共有している状態になる
配列の要素の長さが変わった時にコピーされる

**例えば**

```swift
var a = [1, 2, 3]
var b = a
var c = a
```

配列変数を定義する
最初のindexは全て 1

```swift
println(a[0])
// 1
println(b[0])
// 1
println(c[0])
// 1
```

42をa[0]に代入すると他のも同じように変わる
同じものを参照している

```swift
a[0] = 42
println(a[0])
// 42
println(b[0])
// 42
println(c[0])
// 42
```

新しい値を追加するとコピーを作成し別のものになる

```swift
a.append(4)
a[0] = 777
println(a[0])
// 777
println(b[0])
// 42
println(c[0])
// 42
```

### Ensuring That an Array Is Unique（配列のユニーク化）
#### unshare()
unshareメソッドを呼ぶ事で、共有していいた配列の要素から切り離され新しく独立した配列データになる
ちなみに定数はunshareできない

上記の例の続きで

```swift
b.unshare()
```

配列bがunshareを読んで、異なるデータになる
a, b, c 全て違う配列になった

```swift
b[0] = -105
println(a[0])
// 777
println(b[0])
// -105
println(c[0])
// 42
```

```===``` や ```!==``` を使って同じものを参照しているか確認できる

```swift
if b === c {
	println("b and c は同じ配列の要素をシェアーしている")
} else {
    println("b and c は新しい配列の要素を参照している")
}
// prints "b and c は新しい配列の要素を参照している"
```

以下の様にも書ける

```swift
if b[0...1] === b[0...1] {
	println("These two subarrays share the same elements.")
} else {
	println("These two subarrays do not share the same elements.")
}
// prints "These two subarrays share the same elements."
```

### Forcing a Copy of an Array（配列の強制複写）
#### copy
明示的にコピーする場合、copyメソッドを使う
浅いコピーで新しい配列をつくる

名前の配列をつくって、copiedNames に明示的にコピーする

```swift
var names = ["Mohsen", "Hilary", "Justyn", "Amy", "Rich", "Graham", "Vic"]
var copiedNames = names.copy()

copiedNames[0] に "Mo" を代入しても、オリジナルは変化なし
```swift
copiedNames[0] = "Mo"
println(names[0])
// prints "Mohsen"
```

> **NOTE**
unshareは必要に応じてコピーするが、copyは必ず呼ばれたときに複写する