Start Developing iOS Apps (Swift)


Enumerations and Structures(列挙型と構造体)

```
クラスはSwiftのデータ型を定義する唯一の方法ではありません。
Enumerations = 列挙型 structures = 構造体はクラスと同じ能力を持っていますが、
異なるコンテキストで使う事ができます。
```

##列挙型は、関連する値を「型」としてまとめたもの。

```
eunm Signal {
    case Blew
    case Yellow
    case Red
}

var s: Signal // 変数sに対してSignalを継承
s = Signal.Blue
s = .Blue // 型 => Signalは省略出来る
```

列挙型の内部表現の型を次のように明示的に指定する事も出来ます。

```
enum Signal: Int {
    case Blue
    case Yellow
    case Red
}

let s = Signal.Yellow

print(s.toRow()) //1  //toRowメソッドで実際の値を参照可能

let signal = Signal.fromRaw(2) // Signal.Red
```

##構造体は継承のできないクラス

```
・複数の値を1個のオブジェクトで管理出来る
・辞書とは違い、同じ構造のオブジェクトを複製する事が出来る
・クラスとは違い、「継承できない」
・クラスが参照型であるのに対して、構造体は値型
・イニシャライズも関数も使える
```



```

基本的な書き方(初期値有り、無しOk)

struct 名前 {
    var hogehoge:型
    var gugaguga:型
    let weiwei:型
}

```

```
インスタンスの作りかた

//初期値なし
struct SmartPhone {
    var os:String
    var version:Double
    var width:Int
    var height:Int
}

//初期値あり
struct IPhone5 {
    var os:String = 'iOS'
    var version:Double = 7.0
    var width:Int = 320
    var height:Int = 555
}


//初期値なしの場合、インスタンス生成時に初期値を入れる
var iPhone6 = SmartPhone(os: 'iOS', version: 8.3, width: 375, height: 777)
print(iPhone6.width) //375

//初期値ありの場合、そのままインスタンス化
var iPhone5 = IPhone5()
print(iPhone.width) //320

```

```
イニシャライザの定義

struct Box {
    let width:Int
    let height:Int
    let size:String
    
    //イニシャライザ
    init(width:Init, height:Init){
        //未確定の変数を確定している
        self.width = width 
        self.height = height
        
        var sumsize = width+height
        
        switch (sumSize) {
        case 0...100:
            size = "S"
        case 101...200:
            size = "M"
        case 201...300:
            size = "L" 
        default:
            size = "Free"       
        }
    }
}

//Boxをインスタンス化(initはメソッドを呼び出す)
var newBox = Box(width: 100, height: 30)
print(newBox.size)

```

#参照型と値型の違い

```
クラス => 参照型 (型の実際の値への参照によって表されるデータ型)
         変数に参照型が割り当てられているとその変数は、元の値を参照します。
構造体 => 値型 (型の実際の値によって表されるデータ型)
         変数に値型が割り当てられるとその変数には、値の新しいコピーが代入されます。
```



参考URL http://qiita.com/koher/items/bcdbf6578b6edd1f9e0c
       http://www.weblio.jp/content/%E5%8F%82%E7%85%A7%E5%9E%8B

##Protocols

```

プロトコルはメソッド、プロパティ、もしくは必要とされる特定の要件、機能の一部の詳細な設計図を定義します。(インターフェース)
プロトコルはプロトコル内部の機能を実行する事はありません。
それらの機能は記述されるだけです。
そしてプロトコルはクラス、構造体、もしくは列挙体に対してそれらの機能を提供し実際に実行処理させるよう適合させる事ができます。
つまり、プロトコルは機能を提供しています。
どんな型でもプロトコルの機能に対して適合する事ができます。
```

```
プロトコル(JavaでいうところのインターフェースをSwiftではプロトコルという)を他言語だと実装する = inplement というが、Swiftでは、適合する = conform to adapt to という。

インターフェース => 実装についての情報をもたないメソッドの集合について宣言をする機能。(実際の宣言自体は、各クラスや構造体、列挙体で行う。)

参考URL
http://outofmem.tumblr.com/post/89738775444/swiftapple%E3%81%AE%E6%96%B0%E8%A8%80%E8%AA%9Eswift%E3%81%AE%E3%83%AA%E3%83%95%E3%82%A1%E3%83%AC%E3%83%B3%E3%82%B9%E3%82%92%E8%AA%AD%E3%82%8016-protocols

```

```

protocolを定義

protocolと記述する事で、プロトコルを使用する事を宣言する。
使用するプロトコルの先頭文字は大文字


//プロトコルの宣言
protocol ExampleProtocol {  
    
    //プロパティの宣言
    //{get}は、simpleDescriptionの値を変更せず、表示するのみにしたいために記述している
    var simpleDescription: String {get}
    //メソッドの宣言
    func adjust()
}

参考URL
http://dev.eyewhale.com/archives/1192

```

```
class Monster: ExampleProtocol  
    //プロトコルに適合させる。 型名のあとに「:」をつけて宣言する
    func adjust()

```

```
class Monster: ExampleProtocol, SomeProtocol {
    //複数のプロトコルを適合させる場合は、「,」で区切る
}  

```

```
プロトコルは、特定のインスタンスプロパティ、インスタンスメソッド、タイプメソッド、オペレーター、そして、サブスクリプト(サブスクリプトとは、配列やディクショナリの要素にアクセスする時等に使う添字式)を持つ「型」を使用することができます。
プロトコルは、特定のインスタンスメソッドやタイプメソッドを適合する型に処理、実行することできます。
これらのメソッドはプロトコルに対して中かっこやメソッドの中身(body)を除いて定義することができます。

クラス、構造体、そして列挙体はプロトコルに適合、実装できます。
それらは、プロトコルの名前を:で隔てて記述します。
もしもスーパークラスを記述したいのなら、その名前は最もリストの一番初めに記述します。
```

```
// Simpleクラスを宣言 ExampleProtocolを適合(実装)
class SimpleClass: ExampleProtocol {
    //変数を宣言 文字列型 
    var simpleDexcription: String = "A vary simple class"
    //変数を宣言 数値型
    var anotherProperty: Int = 69105
    //メソッドを宣言 simpleDescriptionに文字連結をおこなう。
    func adjust() {
        simpleDescription += " Now 100% adjusted "
    }
}

//変数aをSimpleClassのインスタンスにする。
var a = SimpleClass()
//インスタンス変数aがSimpleクラスのメソッドを使用する。
a.adjust()
//定数aDescriptionにa.simpleDescriptionを代入する。
let aDescription = a.simpleDescription
```

```
プロトコルは、最初のクラスの型を他の名前の型のように扱うことができます。
あなたが、ExampleProtocolをarray型で生成し、そしてadjust()メソッドをそれぞれのインスタンスに呼び出す時にプロトコルの処理をひとつずつインスタンスに対して実行することができます。
```

```
//クラスとプロトコルを宣言
class SimpleClass2: ExampleProtcol {
    //変数を宣言
    var simpleDescription: String = "Another very simple class"
    //メソッドを宣言
    func adjust() {
        simpleDescription += " Adjusted"
    }
}

//変数を宣言そして、型にExampleProtocolを宣言する。(ExapmleProtocolのメソッドを使用できる。)
// 変数の型を指定し、変数に対して[SimpleClass(), SimpleClass(), SimpleClass2()]を代入する。
//for inメソッドに定数instanceにprotocolArrayの値をひとつずつ入れて、内部処理をおこない、その結果を順に返す。
//for inメソッドは型を指定する必要がある。

var protocolArray: [ExampleProtocol] = [SimpleClass(), SimpleClass(), SimpleClass2()]

for instance in protoclArray {
    instance.adjust()
}

protocolArray

```