Swift - 通过协议 Protocol 共享代码

452 阅读2分钟

常用共享代码的方式有:继承、拓展和全局方法。今天笔者分享一种通过 Protocol 共享代码的技巧。

准备工作

我们先构建一个类,一个结构体和一个枚举。它们都有一个 String 类型的属性 name。而且它们都有一个叫 printName 的方法,可以用来输出 name

class PersonClass {
    let name = "David"
    
    func printName(){
        print(name)
    }
}

struct PersonStruct {
    let name = "David"
    
    func printName(){
        print(name)
    }
}

enum PersonEnum {
    var name: String {
        return "David"
    }
    
    case someone
    
    func printName() {
        print(name)
    }
}

因为 PersonClassPersonStructPersonEnumprintName 方法所做的业务是一模一样的,所以把这方法抽离出来放在一个统一的地方,会更方便维护和拓展。

构建协议

我们先构建一个名为 PrintNameProtocol 的协议。在这个协议里我们定义一个 String 类型的接口 name。并在拓展中添加一个具体的实现方法 printName

protocol PrintNameProtocol {
    var name: String { get }
}

extension PrintNameProtocol {
    func printName() {
        print(name)
    }
}

接着我们让 PersonClassPersonStructPersonEnum 去实现这个协议。

class PersonClass: PrintNameProtocol {
    let name = "David"
}

struct PersonStruct: PrintNameProtocol {
    let name = "David"
}

enum PersonEnum: PrintNameProtocol {
    var name: String {
        return "David"
    }
    
    case someone
}

因为 PersonClassPersonStructPersonEnum 都有 String 类型的属性 name,所以它们都是实现了 PrintNameProtocol 所定义的接口的。接着,我们删除 printName 方法,因为这个方法已经在 PrintNameProtocol 中实现了。

使用共享代码

接着我们初始化一个 personClass 类对象,一个personStruct 结构体和一个枚举 personEnum。并调用一下 printName 方法。

let personClass = PersonClass()
let personStruct = PersonStruct()
let personEnum = PersonEnum.someone

personClass.printName()
personStruct.printName()
personEnum.printName()

控制台输出:

David
David
David

拓展共享代码

下面我们再拓展一下 printName 这个方法。

extension PrintNameProtocol {
    func printName() {
        print("Hello! My name is \(name)")
    }
}

重新运行代码后,控制台输出:

Hello! My name is David
Hello! My name is David
Hello! My name is David

小结

通过拓展协议,我们实现了在类、结构体和枚举中共享代码。这种方式比继承更为灵活和强大。这种共享的方式也方便我们去维护和拓展某些业务代码。