Swift学习5---协议(protocol)和扩展(extension)

Swift学习5---协议(protocol)和扩展(extension)

1.协议

  Swift使用protocol定义协议:

protocol ExampleProtocol {
    var simpleDescription: String { get }
    mutating func adjust()
}

  类型、枚举和结构都可以实现协议:

class SimpleClass: ExampleProtocol {
    var simpleDescription: String = "A very simple class."
    var anotherProperty: Int = 69105
    func adjust() {
        simpleDescription += " Now 100% adjusted."
    }
}
var a = SimpleClass()
a.adjust()
let aDescription = a.simpleDescription

struct SimpleStructure: ExampleProtocol {
    var simpleDescription: String = "A simple structure"
    mutating func adjust() {
        simpleDescription += " (adjusted)"
    }
}
var b = SimpleStructure()
b.adjust()
let bDescription = b.simpleDescription

笔记:

1.Protocol(协议)用于统一方法和属性的名称,而不实现任何功能。协议能够被类,枚举,结构体实现,满足协议要求的类,枚举,结构体被称为协议的遵循者

2.属性要求

  通常前置var关键字将属性声明为变量。在属性声明后写上{ get set }表示属性为可读写的。{ get }用来表示属性为可读的。即使你为可读的属性实现了setter方法,它也不会出错。

protocol SomeProtocol {

var musBeSettable : Int { get set }

var doesNotNeedToBeSettable: Int { get }

}

3.方法要求

  协议能够要求其遵循者必备某些特定的实例方法和类方法。协议方法的声明与普通方法声明相似,但它不需要方法内容.

  协议方法支持变长参数(variadic parameter),不支持默认参数(default parameter)。

4.突变方法要求

        能在方法或函数内部改变实例类型的方法称为突变方法。在值类型(Value Type)(译者注:特指结构体和枚举)中的的函数前缀加上mutating关键字来表示该函数允许改变该实例和其属性的类型

        类中的成员为引用类型(Reference Type),可以方便的修改实例及其属性的值而无需改变类型;而结构体和枚举中的成员均为值类型(Value Type),修改变量的值就相当于修改变量的类型,而Swift默认不允许修改类型,因此需要前置mutating关键字用来表示该函数中能够修改类型

         用class实现协议中的mutating方法时,不用写mutating关键字;用结构体,枚举实现协议中的mutating方法时,必须写mutating关键字

5.协议类型

     协议本身不实现任何功能,但你可以将它当做类型来使用

使用场景:

  作为函数,方法或构造器中的参数类型,返回值类型

  作为常量,变量,属性的类型

  作为数组,字典或其他容器中的元素类型

6.在扩展中添加协议成员

7.通过扩展补充协议声明:当一个类型已经实现了协议中的所有要求,却没有声明时,可以通过扩展来补充协议声明

8.集合中的协议类型:协议类型可以被集合使用,表示集合中的元素均为协议类型

9.协议的继承:协议能够继承一到多个其他协议。语法与类的继承相似,多个协议间用逗号,分隔

10.协议合成:一个协议可由多个协议采用protocol<oneProtocol,twoProtocol>这样的格式进行组合,称为协议合成(protocol composition)。

11.检验协议的一致性

  使用is检验协议一致性,使用as将协议类型向下转换(downcast)为的其他协议类型

   is操作符用来检查实例是否遵循了某个协议。

   as?返回一个可选值,当实例遵循协议时,返回该协议类型;否则返回nil

   as用以强制向下转换型。

  @objc用来表示协议是可选的,也可以用来表示暴露给Objective-C的代码,此外,@objc型 协议只对类有效,因此只能在类中检查协议的一致性。

12.可选协议要求

   在协议中使用@optional关键字作为前缀来定义可选成员。

   可选协议在调用时使用可选链

   可选协议只能在含有@objc前缀的协议中生效。且@objc的协议只能被类遵循。

13.Swift 标准库中定义了一个Equatable协议,该协议要求任何遵循的类型实现等式符(==)和不等符(!=)对任何两个该类型进行比较。所有的 Swift 标准类型自动支持Equatable协议

2.扩展

  扩展用于在已有的类型上增加新的功能(比如新的方法或属性),Swift使用extension声明扩展:

extension Int: ExampleProtocol {
    var simpleDescription: String {
        return "The number (self)"
    }
    mutating func adjust() {
        self += 42
    }
}
7.simpleDescription

1.Swift使用extension声明扩展

2.Swift 中的扩展可以:

  (1)添加计算型属性和计算静态属性: 扩展可以添加新的计算属性,但是不可以添加存储属性,也不可以向已有属性添加属性观测器(property observers)。

  (2)定义实例方法和类型方法 :扩展可以向已有类型添加新的实例方法和类型方法.通过扩展添加的实例方法也可以修改该实例本身。结构体和枚举类型中修改self或其属性的方法必须将该实例方法标注为mutating,正如来自原始实现的修改方法一样。

  (3)提供新的构造器:扩展能向类中添加新的便利构造器,但是它们不能向类中添加新的指定构造器或析构函数。指定构造器和析构函数必须总是由原始的类实现来提供。

  (4)定义下标:扩展可以向一个已有类型添加新下标

  (5)定义和使用新的嵌套类型:扩展可以向已有的类、结构体和枚举添加新的嵌套类型

  (6)使一个已有类型符合某个协议 :一个扩展可以扩展一个已有类型,使其能够适配一个或多个协议(protocol)