Swift是面向协议编程的原因

什么是面向协议编程

在介绍为何说Swift是面向协议编程之前,我们先来了解一下什么是面向协议编程。面向协议编程是一种编程范式,它将重点放在定义和使用协议上,通过协议来实现代码的复用和灵活性。

在传统的面向对象编程中,我们使用类来组织代码,通过继承和多态来实现代码的复用和抽象。而在面向协议编程中,我们将更多的关注于协议的定义和使用,通过协议来约定一个对象需要实现的属性和方法,从而实现代码的复用和灵活性。

面向协议编程的优点包括:

  • 灵活性:通过协议,我们可以定义一组需要实现的属性和方法,一个对象可以同时遵守多个协议,从而实现更灵活的代码组合和复用。不同于继承的单继承限制,一个对象可以遵守多个协议,从而可以在不同的上下文中进行不同的组合。
  • 解耦合:通过协议,我们可以将对象的定义和实现分离开来,对象只需要关注自己需要实现的协议,而不需要关心具体的实现细节。这种解耦合的设计让代码更易于维护和测试。
  • 代码重用:通过协议的组合,我们可以更灵活地组合代码。多个对象可以遵守同一个协议,从而实现代码的重用。同时,我们也可以通过协议扩展来提供一些默认的实现,减少代码的重复。

Swift中的协议

在介绍为何说Swift是面向协议编程之前,我们先来看一下Swift中的协议是如何定义和使用的。

定义协议

在Swift中,我们可以通过protocol关键字来定义一个协议。一个协议可以包含属性、方法、初始化器以及下标等。

protocol Animal {
    var name: String { get set }
    func makeSound()
}

extension Animal {
    func makeSound() {
        print("Animal makes sound")
    }
}

上述代码定义了一个名为Animal的协议,它包含一个可读可写的name属性和一个makeSound方法。协议中的方法可以有默认的实现,我们可以通过协议扩展来提供这些默认实现。

遵守协议

一个对象可以通过classstruct或者enum关键字来定义,并通过:符号来遵守一个或多个协议。

struct Cat: Animal {
    var name: String
    
    func makeSound() {
        print("Meow!")
    }
}

上述代码定义了一个名为Cat的结构体,它遵守了Animal协议,并实现了name属性和makeSound方法。这样,我们就可以使用Cat对象来表示一只猫,并调用协议中定义的属性和方法。

协议组合

在Swift中,我们可以将多个协议组合在一起形成一个新的协议,这样一个对象就需要同时遵守这些协议。

protocol Flyable {
    func fly()
}

protocol Swimmable {
    func swim()
}

protocol Duck: Flyable, Swimmable { }

上述代码定义了两个协议FlyableSwimmable,然后我们通过协议组合定义了一个Duck协议,要求对象同时遵守FlyableSwimmable协议。

协议作为类型

在Swift中,协议可以作为一个类型来使用。我们可以将一个遵守了某个协议的对象赋值给协议类型的变量或常量。

func makeAnimalSound(animal: Animal) {
    animal.makeSound()
}

let cat = Cat(name: "Tom")
makeAnimalSound(animal: cat)

上述代码中,我们定义了一个`make