Swift里协议protocol

本文详细探讨了Swift中的协议,包括协议定义、遵循协议的语法、属性和方法要求、异变方法、构造器要求、协议作为类型、委托、协议扩展等。重点介绍了如何在扩展中实现协议以及协议的继承和组合。同时,文章提到了类专属协议、协议一致性检查以及可选协议要求。通过学习,读者将更深入地了解Swift中协议的使用和设计模式。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

协议定义

协议规定了用来实现某一特定任务或者功能的方法、属性,以及其他需要的东西。结构体枚举都可以遵循协议,并为协议定义的这些要求提供具体实现。

协议语法

protocol SomeProtocol {
    // 这里是协议的定义部分
}

遵循协议语法

结构体: 协议1, 协议2
struct SomeStructure: FirstProtocol, AnotherProtocol {
    // 这里是结构体的定义部分
}

类:父类, 协议1, 协议2
class SomeClass: SomeSuperClass, FirstProtocol, AnotherProtocol {
    // 这里是类的定义部分
}

属性要求

协议可以要求遵循协议的类型提供特定名称和类型的实例属性类型属性。协议不指定属性是存储属性还是计算属性,它只指定属性的名称和类型。此外,协议还指定属性是可读的还是可读可写的

如果协议要求属性是可读可写的,那么该属性不能是常量属性或只读的计算型属性。如果协议只要求属性是可读的,那么该属性不仅可以是可读的,如果代码需要的话,还可以是可写的

协议实例属性的声明
protocol SomeProtocol {
    var mustBeSettable: Int { get set } //类型声明后加上 { set get } 来表示属性是可读可写
    var doesNotNeedToBeSettable: Int { get }  可读属性
}

协议类型属性的声明
protocol AnotherProtocol {
    static var someTypeProperty: Int { get set }
    //定义类型属性 使用 static 或 class 关键字作为前缀
}

protocol FullyNamed {
    var fullName: String { get }
}

协议使用遵循 FullyNamed 协议的简单结构体。

struct Person: FullyNamed {
    var fullName: String
}
let john = Person(fullName: "John Appleseed")
// john.fullName 为 "John Appleseed"

使用2: 协议属性被用作于计算属性
class Starship: FullyNamed {
    var prefix: String?
    var name: String
    init(name: String, prefix: String? = nil) {
        self.name = name
        self.prefix = prefix
    }
    var fullName: String {
        return (prefix != nil ? prefix! + " " : "") + name
    }
}
var ncc1701 = Starship(name: "Enterprise", prefix: "USS")
// ncc1701.fullName 为 "USS Enterprise"

方法要求

协议可以要求遵循协议的类型实现某些指定的实例方法或类方法。不支持为协议中的方法提供默认参数。

类方法的时候,总是使用 static 关键字作为前缀。即使在类实现时,类方法要求使用 class 或 static 作为关键字前缀

类方法协议定义
protocol SomeProtocol {
    static func someTypeMethod() //类方法用static或class 关键字作前缀
}

实例方法的协议:
protocol RandomNumberGenerator {
    func random() -> Double
}

使用示例

class LinearCongruentialGenerator: RandomNumberGenerator {
    var lastRandom = 42.0
    let m = 139968.0
    let a = 3877.0
    let c = 29573.0
    func random() -> Double {
        lastRandom = ((lastRandom * a + c).truncatingRemainder(dividingBy:m))
    // truncatingRemainder 浮点数取余方法,swift3之后使用       

        return lastRandom / m
    }
}
let generator = LinearCongruentialGenerator()
print("Here's a random number: \(generator.random())")
// 打印 “Here's a random number: 0.37464991998171”
print("And another one: \(generator.random())")
// 打印 “And another one: 0.729023776863283”

异变方法协议要求(mutating 关键字)

mutating 关键字作为方法的前缀,写在 func 关键字之前,表示可以在该方法中修改它所属的实例以及实例的任意属性

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值