swift学习心得-协议

2018-04-14  本文已影响0人  彬至睢阳

协议的功能:swift中的protocol不仅能定义方法还能定义属性,配合extension扩展还能提供一些方法的默认实现,而且不仅类可以遵循协议,现在的枚举和结构体也能遵循协议了。只要满足了协议中需求的任意类型都叫做遵循了该协议。

  协议的定义:swift中定义一个协议和定义枚举、结构体或者类的格式是相同的,使用protocol关键字,如下

    定义一个名字为Animal的协议

    protocol Animal {

    }

    协议中定义一个属性,表示遵循该协议的类型具备了某种属性,重点:属性只能使用var关键字声明并且必须明确规定该属性是可读的get、还是可读可写的get set。通过关键字static可以声明一个类型属性。示例如下:

    protocol Animal {

    //定义一个可读可写的 type 属性

    var type: String { get set }

    //定义一个可读的 sexType 属性

    var sexType: String { get }

    //定义一个类属性 namber

    static var namber: String {get}

    }

    //协议中定义方法,swift中的协议可以定义类型方法或者实例方法,方法的参数不能有默认值(swift认为默认值也是一种变相的实现)示例如下:

    protocol Animal {

    //类方法

    static func eat()

    //实例方法

    func changeName()

    }

    //结构体遵循协议。,重点:当我们在结构体中的方法修改到属性的时候需要在方法前面加上关键字mutating表示该属性能够被修改(如果是类不需要添加mutating关键字),这样的方法叫做:异变方法,和 “在实例方法中修改值类型” 的处理是一样的。

    protocol Animal {

    //类方法

    static func eat()

    //实例方法

    mutating  func changeName()

    }

    struct Dog: Animal {

    //类方法

    static func eat(){

    }

    //实例方法

    mutating  func changeName(){

    }

    }

  协议中的初始化器

    我们可以在协议中定义遵循协议的类型需要实现的指定初始化器(构造函数)或者便捷初始化器。

    protocol Animal {

    init(name:String)

    }

    class Cat: Animal {

    var name: String = "Cat"

    required init(name: String) {

    self.name = name

    }

    }

    重点:如果一个类既继承了某个类,而且遵循了一个或多个协议,我们应该将父类放在最前面,然后依次用逗号排列。这是因为Swift中类的继承是单一的,但是类可以遵守多个协议,因此为了突出其单一父类的特殊性,我们应该将继承的父类放在最前面,将遵守的协议依次放在后面。

    多个协议重名方法调用冲突:由于在Swift中并没有规定不同的协议内方法不能重名(这样的规定也是不合理的)。因此我们在自定义多个协议中方法重名的情况是可能出现的,因此我们需要指定调用特定协议的方法,改进后的代码如下:

    let num = (对象 as 协议).方法

    协议的继承、聚合、关联类型

    协议可以继承一个或者多个其他协议并且可以在它继承的基础之上添加更多要求。协议继承的语法与类继承的语法相似,选择列出多个继承的协议,使用逗号分隔。

    除了使用协议的继承外我们还可以使用形如OneProtocol  & TwoProtocol的形式实现协议聚合(组合)复合多个协议到一个要求里

    继承和聚合在使用上的区别:首先协议的继承是定义了一个全新的协议,我们是希望它能够“大展拳脚”得到普遍使用。而协议的聚合不一样,它并没有定义新的固定协议类型,相反,它只是定义一个临时的拥有所有聚合中协议要求组成的局部协议,很可能是“一次性需求”,使用协议的聚合保持了代码的简洁性、易读性,同时去除了定义不必要的新类型的繁琐,并且定义和使用的地方如此接近,见明知意,也被称为匿名协议聚合。但是使用了匿名协议聚合能够表达的信息就少了一些,所以需要开发者斟酌使用。

    协议的检查:如何检查某个类型是否遵循了特定的协议?:使用关键字 is,同时该运算符会返回一个Bool值用于判断条件是否成立。

    如何让定义的协议只能被类遵守?:使用关键字class,该关键字修饰之后表示协议只能被类遵守,如果有枚举或结构体尝试遵守会报错。

    协议的关联类型指的是根据使用场景的变化,如果协议中某些属性存在“逻辑相同的而类型不同”的情况,可以使用关键字associatedtype来为这些属性的类型声明“关联类型”。。唯一要注意的是:一定要在遵守该协议的类型中使用typealias规定具体的类型。不然编译器就报错了。

    协议的扩展:扩展协议的属性和方法,为存在的类型添加协议遵守(简单的来说我们可以对存在的类型(尤其是系统的类型)添加协议遵守)

    扩展可以添加新的属性、方法和下标到已经存在的类型,并且因此允许你添加协议需要的任何需要

    扩展协议的方法

    extension 协议 {

    func 方法()  {

    }

    }

    Swift标准库为我们提供了55种协议,他们的命名很有特点,基本是以"Type"、“able”、“Convertible”结尾,分别表示该协议“可以被当做XX类型”、“具备某种能力或特性”、“能够进行改变或变换”。

上一篇下一篇

猜你喜欢

热点阅读