1、Swift入门学习笔记(第一版),对Swift的基础知识点进行梳理总结。知识点一直在变,只是作为参考,以苹果官方文档为准~
2、在学习完基本的知识点以后会结合官方文档及相关资料,在此版本的基础上进行添加更改。
二十一、协议(1)
在阅读此文的时候,请大家忽略各种类型协议等等的取名,只是为了简化讲解功能,所以名字没有实际意义,取起来比较麻烦,所以有点乱
后半部分:文章链接
类、结构体或枚举类型可遵循协议,并提供具体实现完成协议定义的方法和功能。
除了遵循协议,我们也可对协议进行扩展,实现一些特殊规定或一些附加功能
1、协议的语法
定义协议
protocol SomeProtocol {
// 协议内容
}
结构体遵循多个协议
struct SomeStructure: FirstProtocol,AnotherProtocol {
// 结构体内容
}
class SomeClass: SomeSuperClass,FirstProtocol,AnotherProtocol {
// 类的内容
}
2、对属性的固定
协议可以规定遵循者提供特定名称和类型的实例属性或类属性,必须指明只读还是可读可写
协议要求只读,属性可以使只读,也可以是可读可写
协议要求可读可写,那么属性必须可读可写
类型属性:类型本身特有,不管有多少实例,这些属性只有唯一一份,大家共享。类,枚举,结构体都可以有。static
关键字。如果遵循者是类也可以用class
关键字声明类属性
实例,没有实际意义,纯为了说明功能
protocol SomeProtocol {
static var name:String {get}
var age:Int {get set}
}
//set和get方法是间接获取和设置其他属性或变量的值。set不能set本身,可以利用传入set其他的参数
class Person1:SomeProtocol {
var bornTime:Int = 0
static var name:String {
return "Zhu"
}
var age:Int {
get {
return 2015-bornTime
}
set {
bornTime = 2015-newValue
}
}
}
var person = Person1()
person.age = 20
print(Person1.name,person.bornTime,person.age)
Output:
Zhu 1995 20
3、对方法的规定
3.1、普通方法/类方法/可变参数方法
不需要大括号和方法体。不支持参数默认值。支持定义具有可变参数的方法,写法与普通函数相同,要写参数
类方法可用static
关键字作为前缀。如果协议遵循着是类也可以用class
或static
可变参数:表示不确定数量的输入值,0或多个,传入参数在函数中变为此类型数组,一个函数最多一个可变参数
3.2、对mutating方法的规定
需要在函数中修改它的实例(改self
),适用于值类型(结构体、枚举),mutating
关键字
如果用类实现mutating
方法时,不用写mutating
关键字。结构体或枚举实现时必须要写
protocol OneProtocol {
func classMethod() -> Double
//mutating方法
mutating func mutatingMethod()
//类方法
static func someTypeMethod()
//求算数平均值,传入可变参数,但是写法与普通函数无异
func arithmeticMean(numbers: Double...) -> Double
}
class TestType:OneProtocol {
func classMethod() ->Double {
print("ClassMethod")
return 12.1
}
func mutatingMethod() {
print("类实现mutating方法不用写mutating关键字")
}
static func someTypeMethod() {
print("someTypeMethod")
}
func arithmeticMean(numbers: Double...) -> Double {
var total: Double = 0
for number in numbers {
total += number
}
print(total / Double(numbers.count))
return total / Double(numbers.count)
}
}
var testType = TestType()
testType.classMethod()
testType.mutatingMethod()
TestType.someTypeMethod()
testType.arithmeticMean(1,2.3,4.56)
Output:
ClassMethod 类实现mutating方法不用写mutating关键字 someTypeMethod 2.62
4、对构造器的规定
语法与书写普通构造器一样,但是不需要写花括号和构造器的实体
protocol AnotherProtol {
init()
}
//普通类遵循协议,如果不是final类(不允许继承),需要在构造器方法前加required关键字
class SomeClass:AnotherProtol {
required init() {
print("SomeClass")
}
}
class SomeSuperClass {
init() {
print("SomeSuperClass")
}
}
//协议规定构造器与父类的构造器一样,那么重写要同时表上required和override修饰符
class SomeSupClass:SomeSuperClass,AnotherProtol {
required override init() {
print("SomeSupClass")
}
}
//有final关键字,不允许继承,遵循协议,正常书写方法即可
final class SomeFinalClass:AnotherProtol {
init() {
print("SomeFinalClass")
}
}
同时可在协议中定义可失败构造器,遵循该协议的类型必须添加同名同参数可失败构造器或者非可失败构造器
如果协议定义非可失败构造器,遵循该协议的类型必须添加同名同参数的非可失败构造器或隐式解析类型的可失败构造器(init!
)
5、协议类型
协议本身不实现任何功能,但是可像普通类型一样使用
a、作为函数、方法或构造器中的参数类型或返回值类型
b、作为常量、变量或属性的类型
c、作为数组、字典或其他容器中的元素类型
protocol OtherProtocol { func testPrint() }
class OtherClass:OtherProtocol { func testPrint() { print("~~OtherClass~~") }
}
class OneClass { let function:OtherProtocol init(function:OtherClass) { self.function = function }
func method() { function.testPrint() } } var otherVal = OtherClass() var oneVal = OneClass(function: otherVal) oneVal.method()
定义一个OneClass
类,其参数function
的类型是OtherProtocol
,那么所有遵循OtherProtocol
协议的类型的实例都可以赋值给function
OtherClass
遵循OtherProtocol
协议,可以将其实例赋值给function
Output:
~~OtherClass~~