1. 程式人生 > >【iOS】Swift中擴充套件extension與協議protocol

【iOS】Swift中擴充套件extension與協議protocol

一起連帶前面幾篇Playground小結程式碼都轉到github上了,註釋寫了很多,主要方便自己以後可以翻翻看。Swift語法主要部分差不多就這些了。當然還有泛型、運算子過載、ARC、閉包之類的補充。

一、擴充套件(extension)

擴充套件 extension (類似OC中的分類Swift中沒有名字), 即在沒有許可權獲取到原始程式碼的情況下為類增加新功能.

注意: 只要定義了擴充套件, 那麼該擴充套件對該類的例項都是可用的.

extension SomeType{
    //新增到SomeType的新功能寫在這裡
}

1.1擴充套件屬性(只能是計算屬性)

//擴充套件可以新增新計算屬性, 但是不能新增儲存屬性(也不可以新增屬性觀察).
extension Double{  //為API中的已有型別新增例項屬性
    var km : Double { return self * 1_000.0 }
    var m : Double { return self }
    var cm : Double { return self / 100.0 }
}

let jjLength = 1.m  // 1與m進行點運算, 表示1的Double值
let jjLength_km = 1.km
println(10.km + 1.m)

1.2擴充套件構造器

//可以定製自己的構造器
class MyClass{
    var a : Int
    init(){
        a = 10
    }
}

extension MyClass{
    convenience init(var parm:Int){   //擴充套件構造器
        self.init()
        println("擴充套件構造器--->便利構造器, \(parm)")
    }
}

var myClass = MyClass(parm: 9)

1.3擴充套件方法

下面是像Int中擴充套件myIntFunc方法

extension Int{
    func myIntFunc(){
        println("值為\(self) , 哈哈哈哈!")
    }
}

1.myIntFunc()

1.3.1 修改例項方法

通過擴充套件方法, 可以修改該例項self本身.但是方法前要加 mutating

extension Double{
    mutating func myMoidfySelfValue{
        self = self * self //修改self例項的值
    }
}

var d = 2.0
d.myMoidfySelfValue()

1.4 擴充套件巢狀型別

即向已有的巢狀型別中新增新的巢狀型別. 還可以擴充套件下標(附屬指令碼).

extension Character {
    enum Kind{   //嵌套了一個列舉型別
        case Big
        case Small
    }
    var k : Kind{
        if(String(self).lowercaseString == "a"){
            return Kind.Big
        }else{
            return Kind.Small
        }
    }
}
var ch : Character = "a"
ch.k   //返回一個列舉值Kind.Big

二、協議(protocol)

可定義方法與屬性, 由具體的類去實現. 越來越像Java

Swift中的協議能被類, 列舉,結構體實現.

protocol SomeProtocol{
    //協議內容
}

class SomeClass : SomeProtocol{ //實現協議, 可實現多個協議
    
}

2.1 協議中屬性/方法/突變方法的要求

2.1.1 屬性的要求

protocol AnotherProtocol1{
    //class表示類成員(結構體/列舉中用static)
    class var property : Int { get set} //get, set 表示可讀可寫
}

class AnotherClass1 : AnotherProtocol1{
    class var property : Int {  //實現協議中的屬性
        get{
            return 10
        }
        set{
            
        }
    }
}

2.1.2 方法要求

//不支援預設引數. 寫法上只是沒有方法的實現.
protocol AnotherProtocol2{
    func myFunc() -> Int   //只宣告不實現
}

class AnotherClass2 : AnotherProtocol2{
    func myFunc() -> Int {  //實現方法
        return 10
    }
}

2.1.3 突變方法要求

能在方法或函式內部改變例項型別的方法稱為突變方法. (mutating關鍵字)

在類中,可以不寫mutating, 但在結構體與列舉中國必須寫

protocol Togg{
    mutating func togg()
}

enum OnOffSwitch : Togg{
    case Off , On
    
    mutating func togg() { //改變例項的值
        switch self{
        case .Off:
            self = On
        case .On:
            self = Off
        }
    }
}

var lightSwitch = OnOffSwitch.Off
lightSwitch.togg()   //值變為On

2.2 協議型別.

協議也可以當做型別來使用. 這點和函式一樣.

1.可作為引數/返回值型別

2.可作為常量/變數/屬性的型別

3.可作為陣列/字典和其他元素型別

protocol MyRect{
    func myLuckNumber() -> Int
}

class MyRectImp : MyRect{
    func myLuckNumber() -> Int {
        return 10
    }
}

class Dice {
    let sides :Int
    var gener : MyRect    //作為型別
    init(sides:Int, gener:MyRect){  //作為引數
        self.sides = sides
        self.gener = gener
    }
}

var dice = Dice(sides: 6, gener: MyRectImp())
dice.gener.myLuckNumber()   //返回10

參考:

The Swift Programming Language  

Apple Dev Center