区分简单理解
- 面向对象: 一个人 名字/年龄/跑/吃
- 面向协议: 是一个人,可以有很多能力(协议)
面向对象
- 传统的面向对象思维方式:
- 有一只狗,有自己的名字, 可以跑
- 有一只猫,有自己的名字, 可以跑
- 有一个人,有自己的名字, 可以跑
- 抽象出一个动物类, 之后, 将跑的行为放入动物类中
- 如果需要一个吃的行为, 也可以抽象在动物类中

- Animal 作为基类,构建跑和吃的行为方法
class Animal: NSObject {
func running() {
print("跑")
}
func eating() {
print("吃")
}
}
- Dog 作为子类,调用父类的方法
- Dog 作为子类 继承自父类
- 子类中 子类重写父类的方法,父类指针指向子类。 多态
- 同理 Cat、Person 也是这样的
- 多态的三个条件
- 继承:各种子类继承自父类
- 重写:子类重写了父类的方法 eating()、running()
- 指向:父类指针指向子类
class Dog : Animal{
override func eating(){
super.eating()
print("狗在吃")
}
override func running(){
super.running()
}
}
- 面向对象开发弊端
- 如果有一个机器人(一辆车), 也有跑的行为, 这个时候如何抽象呢, 显然该抽象方式并不是特别合理
- 显然car、robot不能继承自Animal因为他们不是animal 只能在抽取一个基类或者自己写自己的

class Car: NSObject {
func running() {
}
}
class Robot: NSObject {
func running() {
}
}
- 真实开发场景中
- 对UIViewController/UITableViewController/UICollectionViewController抽象相同的方法
- 所以你可能需要做 BaseViewController/BaseTableViewController/BaseCollectionViewController 三个控制器的基类(还是很复杂)
- 如果你要去别的项目复制部分功能时,有些要复制,有些又不要复制,抽取就比较麻烦了
- 面向对象开发核心是: 封装-继承-(多态)
面向协议示例
- Swift 标准库中有 50 多个复杂不一的协议,几乎所有的实际类型都是满足若干协议的
- 面向协议开发核心是: 模块化(组件化)
- 面向协议开发应用:
- 粒子动画效果实现, 抽取在单独的协议中, 如果有控制器需要, 实现我的协议即可
- 很多UIView会通过xib进行描述, 而我们经常需要从一个xib中加载UIView, 抽取单独的协议, 需要从xib中加载类, 只需要遵守协议即可
简单示例
- 当UIViewController/UITableViewController/UICollectionViewController 都需要一个Test方法时
- 写一个Testable.swift
- 给自定义的协议中添加extension,在extension中对可选方法进行默认实现,这样遵守协议的对象就可以不用实现可选方法.
- 代码示例:
import Foundation
protocol Testable {
func test()
}
extension Testable {
func test() {
print("对代码进行简单测试")
}
}

class OneViewController: UIViewController, Testable
class TwoViewController: UITableViewController, Testable
class ThreeViewController: UICollectionViewController, Testable
重新回到eating和running

import Foundation
protocol Runable {
}
extension Runable {
func running() {
print("正在跑ing")
}
}
import Foundation
protocol Eatable {
}
extension Eatable {
func eating(){
print("正在吃东西ing")
}
}
class Cat: NSObject, Runable {
}
class Person: NSObject, Runable {
}
面向协议的条件 只有当前的类是UIViewController 才能遵守协议
protocol Emitterable {
}
extension Emitterable where Self : UIViewController
网络请求(使用面向协议方式进行开发)
protocol Requestable {
var method : HttpMethod { get }
var host : String { get }
var path : String { get }
var parameters : [String : Any] { get }
associatedtype ResultType : Decodable
}
extension Requestable {
func request(completion : @escaping (ResultType?) -> Void) {
let url = URL(string: host + path)!
let request = URLRequest(url: url)
let task = URLSession.shared.dataTask(with: request, completionHandler: { (data, _, error) in
completion(ResultType.parse(data!))
})
task.resume()
}
}
protocol Decodable {
static func parse(_ data : Data) -> Self?
}