You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Swift中Protocol与Polymorphism对比:面向编程新手的选型疑问

怎么在Protocol和多态之间做选择?

嘿,我刚入门面向对象编程的时候也纠结过这个问题,太懂这种“两种方法好像都能用,到底选哪个”的困惑了!先给你理清楚核心逻辑:Protocol其实是实现多态的一种方式,它们不是对立的,很多时候是配合使用的。下面我结合场景给你拆解什么时候该侧重用哪个:

先搞懂概念关联

  • 多态是面向对象的核心特性,本质就是“同一个行为,不同对象有不同实现”——不管是通过继承父类重写方法,还是通过遵守协议实现方法,都是在做多态。
  • Protocol(协议)是定义一套方法/属性的规范,让任何类(不管有没有继承关系)都能遵守并实现这套规范,属于接口式多态,重点是规范行为,不关心类的继承层级。
  • **Delegate(委托)**是Protocol的典型应用场景,用来实现对象间的解耦通信——比如A让B帮忙处理某个事件,只要B遵守A定义的协议就行,不用A直接依赖B的具体类型。

具体选择场景

1. 当类之间没有继承关系,或者不想用继承时,选Protocol

举个例子:你有Dog、Car、Robot三个完全不相关的类,但都需要实现“发出声音”的功能。如果用继承,你得硬造一个SoundMaker父类让它们继承,但这显然不符合逻辑(狗、车、机器人怎么会是同一个父类的子类?)。

这时候用Protocol就特别优雅:

// 定义协议
protocol Soundable {
    func makeSound()
}

// 不同类分别遵守协议实现
class Dog: Soundable {
    func makeSound() {
        print("汪汪汪!")
    }
}

class Car: Soundable {
    func makeSound() {
        print("嘀嘀嘀!")
    }
}

class Robot: Soundable {
    func makeSound() {
        print("哔哔哔!")
    }
}

这样既实现了“统一调用makeSound(),不同对象有不同表现”的多态,又避免了不合理的继承层级,代码更灵活。

2. 当类有共同父类且共享大部分逻辑时,选继承式多态

比如你有Cat、Dog、Bird,它们都是Animal的子类,大部分属性(age、weight)和方法(eat()、sleep())都一样,只有makeSound()的实现不同。

这时候继承Animal父类就更合适,因为可以复用父类的代码,不用每个类都重复写相同的逻辑:

class Animal {
    var age: Int
    init(age: Int) {
        self.age = age
    }
    
    func eat() {
        print("吃东西")
    }
    
    // 父类定义方法,子类重写(多态的体现)
    func makeSound() {
        fatalError("子类必须重写这个方法")
    }
}

class Dog: Animal {
    override func makeSound() {
        print("汪汪汪!")
    }
}

class Cat: Animal {
    override func makeSound() {
        print("喵喵喵!")
    }
}

这种场景下,继承式多态能帮你减少重复代码,逻辑也更清晰。

3. 需要对象间解耦通信时,用Delegate(基于Protocol)

比如你写一个列表页面,自定义的TableViewCell想把点击事件传给ViewController,但又不想让Cell直接依赖ViewController的具体类型(不然Cell就没法复用在其他页面了)。

这时候就用Delegate模式:

// 定义委托协议
protocol TableCellDelegate: AnyObject {
    func cellDidTap(_ cell: CustomTableCell)
}

class CustomTableCell: UITableViewCell {
    // 委托对象,类型是协议
    weak var delegate: TableCellDelegate?
    
    @IBAction func tapButton(_ sender: UIButton) {
        // 点击时通知委托
        delegate?.cellDidTap(self)
    }
}

// ViewController遵守协议实现方法
class MyViewController: UIViewController, TableCellDelegate {
    func cellDidTap(_ cell: CustomTableCell) {
        print("Cell被点击了!")
    }
    
    // 给Cell设置委托
    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        let cell = tableView.dequeueReusableCell(withIdentifier: "CustomCell", for: indexPath) as! CustomTableCell
        cell.delegate = self
        return cell
    }
}

这里Delegate本质也是多态——任何遵守TableCellDelegate的对象都可以作为Cell的委托,完美实现了对象间的解耦。

总结一下

  • 多态是你要达到的目标,Protocol是实现这个目标的工具之一(另一个是继承);
  • 如果需要跨类的行为规范,或者不想用继承,优先选Protocol;
  • 如果类有共享逻辑的继承层级,优先选继承式多态;
  • Delegate是Protocol的具体用法,专门解决对象间的解耦通信问题。

内容的提问来源于stack exchange,提问作者Andrew Tuzson

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.20 10:35:25