【極客班】Swift高階程式設計二

weixin_34007291發表於2016-05-22

結構與列舉

類與結構的異同:
相同點:都可以定義以下成員:屬性、方法、下標、初始化器;都支援型別擴充套件、協議。
不同點:類支援繼承和多型,結構不支援;類必須自己定義初始化器,結構會有預設的按成員初始化器;類支援析構器,結構不支援;類的例項在堆上,有ARC負責釋放;結構的例項在棧上,棧結構自動釋放,不參與ARC管理;類支援引用相等比較,結構不支援。
列舉:
enum屬於值型別,有值拷貝語義;可以用switch-case語句處理,但case必須包含所有列舉值,否則需要default:

//定義列舉型別
enum Color {
    case Red
    case Green
    case Blue
}

enum ComplexColor{
    case Red,Green,Blue,Alpha
}

同樣可以為enum指定原始值,即raw value,型別可以是字元、字串、整數、或浮點數;數值預設從0開始,字串與列舉值名稱相同:

//指定原始型別
enum WeekDay: Int{
    case Monday=1, Tuesday, Wednesday,Thursday, Friday, Saturday, Sunday
}

var day: WeekDay?
day = WeekDay(rawValue: 7)


var data=WeekDay.Saturday.rawValue

enum支援關聯值,可以設定不同型別的值成員,類似聯合資料結構:

class Point{
    var x=0
    var y=0
    
    init(x:Int, y:Int){
        self.x=x
        self.y=y
    }
}

//列舉關聯值
enum Position{
    case Number(Point)
    case Name(String)
}

var p1=Position.Number(Point(x: 123,y: 588))
var p2=Position.Name("Shanghai People's Square")

繼承與多型

繼承:子類自動繼承基類的屬性、方法、下標;只有類支援繼承,結構和列舉不支援繼承;繼承同時支援例項成員和型別成員:

class Shape{
    var no=0
    
    func move() {
        print("NO: \(no) Shape.move")
    }
}


class Rectangle: Shape{
    var leftUp=Point()
    var width=0
    var height=0
    
}

class Circle: Shape{
    var center=Point()
    var radius=0
}

多型:
子類在同一行為介面下,表現不同的實現方式;子類使用override關鍵字來表示多型定義,也可以使用super來呼叫基類的實現:

class Shape{
    var no=0
    //0x000340
    final func show(){
        print("Shape.show")
    }
    //0x000640
    func move() {
        print("Shape.move")
    }
}
class Rectangle: Shape{
    override var no: Int {
        get{
            print("Rectangle.no.get()")
            return super.no
        }
        set{
            print("Rectangle.no.set()")
            super.no=newValue   
        }
    }  
    //0x000880
    override func move() {
        print("Rectangle.move")
    }    
}

繼承中的初始化器init:如果子類沒有初始化器,則自動繼承;如果子類初始化器與基類初始化器原型一致,必須使用override;在子類中使用基類屬性,必須確保首先呼叫基類初始化器;
繼承中的析構器deinit:如果子類沒有定義析構器,會自動繼承基類析構器;子類析構器執行完畢後,會自動呼叫基類析構器;子類析構器自動具有多型性;

class Base{
    var data1:Int
    init(){
        data1=100
        print("\(data1)")
        print("Base.init")
    }
    
    deinit{
        print("Base.deinit")
    }
}

class Sub: Base{
    var data2=200
     override init(){
        super.init()
        print("\(data1), \(data2)")
        print("Sub.init")
    }
    deinit{
        print("Sub.deinit")
    }
}

協議

型別的合同約定,只描述外部介面,不提供具體實現方法
協議可以包含以下成員:
屬性(協議中可以定義只讀屬性,也可以定義讀寫屬性;協議中可以定義例項屬性、也可以定義型別屬性;協議中只能定義變數屬性,不能定義常量屬性;實現協議時,並不要求實現為儲存屬性、還是計算屬性);
方法(協議可以定義例項方法、也可以定義型別方法;協議中的方法不能定義引數的預設值);
初始化器;
下標;
操作符;
一個型別可以實現多個協議,協議可以應用在如下型別上。但可以新增class關鍵字標明協議只能應用在類上:
類;
結構;
列舉;

//定義協議
protocol Drawable{  
    var discription: String{
        get
    } 
    func draw()   
    init()
    subscript(index: Int) -> Int {
        get
    }
    func ==(lhs: Self, rhs: Self) -> Bool
}
//實現協議
final class Point: Drawable{
    var x:Int
    var y:Int
    init(){
        x=10
        y=10
    }
    var discription: String{
        return "[\(x), \(y)]";  
    }
    func draw(){
        print(self.discription)
    }    
    subscript(index: Int) -> Int {
        return 0
    }
}

協議本質上是一種型別,可以作為宣告型別,但不能建立例項。
協議變數的記憶體模型遵從實際型別的記憶體模型:
引用型別傳參、拷貝採用引用方式;
值型別傳參、拷貝採用傳值方式;

protocol Shape{
    var discription: String{
        get
    }
    mutating func moveTo(x:Int, _ y:Int)
}
class Point: Shape{
    var x=10
    var y=20
    func moveTo( x: Int, _ y: Int) {  
        self.x=x
        self.y=y
    } 
    var discription: String{
        return "[\(x), \(y)]"
    } 
    func display(){
        print(self.discription)
    }
}

檢查協議型別
使用is檢查型別是否實現了協議:

if(item1 is AProtocol){
    print("the runtime type of item1 conforms Shape protocol")
}
if(item2 is AProtocol){
    print("the runtime type of item2 conforms Shape protocol")
}

使用as?和as!將型別下溯轉型為協議:

item3 = item1 as? AProtocol
item3 = item2 as? AProtocol

相關文章