文章摘要
GPT 4
此内容根据文章生成,并经过人工审核,仅用于文章内容的解释与总结

说在前面

视频教程看了一半,先发表一个暴论:swift协议 protocol 跟Java的 抽象类 有什么区别?先继续看吧。

协议 protocol

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
protocol Person{
var age:Int {get set}
var name:String {get}
func sayHello()
}

struct Worker:Person{
var age: Int
var name: String
func sayHello() {
print("我是一个\(age)岁的\(name)")
}
}

struct Boss:Person{
var age: Int
var name = "老板"
func sayHello() {
print("我是一个\(age)岁的\(name)")
}
}
let worker = Worker(age: 27, name: "员工")
worker.sayHello()
let boss = Boss(age: 30)
boss.sayHello()
//输出:
//我是一个27岁的员工
//我是一个30岁的老板
  • 协议的属性:可以指定属性是只读(get)还是读写(get 和 set),但 不指定属性的存储细节
  • 协议的方法:可以指定方法的名称、参数和返回类型,但 不包含方法的实现
  • 协议继承:协议可以继承其他协议,从而形成层次结构,子协议可以添加新的要求或细化父协议的要求。

真真Java抽象类,有细节略微不同,但以后用到再重新补充,概念上的内容不太容易描述。

例子的话,View 视图,之前写小demo时,我知道几乎所有控件都是 xxView ,想必都遵循了 View 这个协议。
(ps:类叫继承,接口叫实现,协议叫遵循

Equatable

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
import UIKit

func getRandomNumber() -> Int{
Int.random(in: 1...6)
}

func getRandomNumber2() -> some Equatable{
Int.random(in: 1...6)
}

func getRandomNumber3() -> some Equatable{
Double.random(in: 1...6)
}

print(getRandomNumber() == getRandomNumber())
print(getRandomNumber2() == getRandomNumber2())

Equatable 这个是 Swift 中的一个协议,用于定义类型之间的相等性比较规则,但实际的用法未来实际用到再拓展。

扩展 Extension

1
2
3
4
5
6
7
import UIKit

var str = " Hello,world "
let trimmed = str.trimmingCharacters(in: .whitespacesAndNewlines)
print(trimmed)
//输出:
//Hello,world

trimmingCharacters 这个方法要 import 专门的包才有

比如我们要去除字符串中的空行等,像Java,JS好像都有自带的api .trim() ,但是swift自身没有,这时候你就可以用到 extension 关键字来自己封装一个方法。

另外还发现个小知识点,两台电脑上自动生成的import不一样,分别是 CocoaUIKit ,查了一下 Cocoa 适用于 macOS 开发,UIKit 适用于 iOS 和 iPadOS 开发。

1
2
3
4
5
6
7
8
9
10
11
import UIKit

extension String{
func trim() -> String {
self.trimmingCharacters(in: .whitespacesAndNewlines)
}
}
var str = " Hello,world "
let trimmed = str.trim()
//输出:
//Hello,world

上述写的 extension 给 String 拓展了一个新方法的实现,这个Java还真没有,最多拷贝出来原来的类改改名字加个方法,硬要说相当于工具类util吧。

总结

  • 协议就像是代码的契约。
  • 不透明返回类型让我们可以在代码中隐藏一些信息。
  • 扩展让我们能够为现有类型添加功能。
  • 协议扩展让我们能够一次性为多个类型添加功能。

课后作业

制定一个描述建筑物的协议。
你的协议应包含以下内容:

  • 一个存储建筑物房间数量的属性。
  • 一个将成本存储为整数的属性。
  • 一个存储出售该建筑物的房地产经纪人姓名的属性。
  • 一个打印建筑物销售摘要的方法。
  • 创建两个符合该协议的结构体,房屋(House)和办公室(Office)。

提示:

  • 在涉及任何结构体之前,先完整地设计协议。
  • 不能在协议中提供方法的实现。
  • 由你决定哪些应该是只读属性,哪些应该有存取器(getter 和 setter)。
  • 使用 {get} 或 { get set } 来控制属性的读写状态。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
protocol Building{
var type: String{get}
var room: Int{get}
var cost: Int{set get}
var saler: String{set get}
}

extension Building{
func printSummary(){
print("这个建筑是\(type),有\(room)个房间,联系\(saler)花费\(cost)可以购买它")
}
}

struct House: Building {
var type = "房屋"
var room: Int
var cost: Int
var saler: String
}

struct Office: Building {
var type = "办公室"
var room: Int
var cost: Int
var saler: String
}

let house = House(room: 4, cost: 1000, saler: "易困")
house.printSummary()
let office = Office(room: 100, cost: 1000_000, saler: "Yikun")
office.printSummary()
//输出
//这个建筑是房屋,有4个房间,联系易困花费1000可以购买它
//这个建筑是办公室,有100个房间,联系Yikun花费1000000可以购买它