IOS面试题——Swift协议与面向协议编程,协议实现前缀(13)

一 面试题汇总

  1. 什么是协议?协议能添加什么?
  2. 协议中定义的内容是否必须全部都实现?如果想要实现可选协议呢?
  3. 实现协议时的属性权限要不小于协议中定义的属性权限
  4. 协议中定义的init方法,能否用init?来实现?
  5. 枚举值如何进行遍历?遵守CaseIterable协议
  6. 自定义打印需要遵循什么协议?CustomStringConvertible、 CustomDebugStringConvertible
  7. Any、AnyObject有什么区别?如何定义只能类遵守的协议?
  8. 什么是面向协议编程?解决了面向对象编程哪些问题?
  9. 如何利用协议实现前缀效果?

二 面试题解答(仅供参考)

2.1 什么是协议?协议能添加什么?

1
2
3
4
5
6
7
8
9
10
11
在 Swift 中,协议(Protocol)定义了一组方法、属性或其他要求,供遵循该协议的类型(类、结构体、枚举)来实现。
协议本质上是行为规范。

协议能添加的内容:

1.方法:声明实例方法和类型方法(static/class)。
2.属性:声明实例属性和类型属性(var),可指定为 get 或 get set。
3.初始化器:定义初始化要求(init)。
4.关联类型:使用 associatedtype 定义占位类型,延迟类型确定。
5.协议继承:一个协议可以继承多个协议。
6.可选要求(仅限 @objc 协议):通过@objc optional标记方法或属性为可选(需搭配@objc使用,限用在类或 @objc 类型上)

2.2 协议中定义的内容是否必须全部都实现?如果想要实现可选协议呢?

1
2
普通协议:所有要求必须实现。
可选协议:用 @objc 和 @objc optional,但仅限类使用。

2.3 实现协议时的属性权限要不小于协议中定义的属性权限

1
2
访问级别:实现时不能低于协议定义的权限。
读写权限:{ get } 可升级为 { get set },但反过来不行。

2.4 协议中定义的init方法,能否用init?来实现?

1
2
普通 init → 可以用 init 或 init? 来实现(降级)。
可失败 init? → 只能用 init? 或 init! 来实现(不能升级)。

2.5 枚举值如何进行遍历?遵守CaseIterable协议

1
遵守 CaseIterable,用 allCases 来遍历所有枚举值!

2.6 自定义打印需要遵循什么协议?CustomStringConvertible、 CustomDebugStringConvertible

1
2
3
4
CustomStringConvertible:用于普通打印(print())。

CustomDebugStringConvertible:用于调试打印(debugPrint())。
都需要实现相应的 description 或 debugDescription 属性,返回自定义的字符串表示。

2.7 Any、AnyObject有什么区别?如何定义只能类遵守的协议?

1
2
3
Any:表示任意类型(包括值类型和引用类型)。
AnyObject:表示任意类的实例(只限引用类型)。
类遵守的协议:通过在协议声明中使用 class 或 AnyObject 约束,确保只有类类型可以遵守该协议。

2.8 什么是面向协议编程?解决了面向对象编程哪些问题?

1
2
3
4
面向协议编程(POP)强调通过协议来定义行为,解耦类型和功能。

它解决了 面向对象编程(OOP)中的继承问题、多重继承问题以及灵活性差的问题,
并提升了代码的复用性、可扩展性和可测试性。

2.9 如何利用协议实现前缀效果?

1
2
3
4
5
6
7
8
9
10
在 Swift 中,可以利用协议来实现前缀效果,即让不同的类型通过遵循协议来共享相同的行为或功能。
通过协议和协议扩展(extension),我们可以为不同类型提供统一的前缀功能。

1-关键点:
1.1-通过协议 Prefixable 定义统一的接口。
1.2-使用协议扩展提供默认的前缀功能,这样所有遵循该协议的类型都会自动拥有相同的前缀行为。
1.3-每个类型可以使用该协议定义的默认实现,也可以在需要时重写它。

2-总结:
通过协议和协议扩展,可以实现跨类型共享统一的前缀功能,使得代码更加简洁且易于扩展。

三 参考

  • 简书—Swift协议与面向协议编程,协议实现前缀