采用协议时如何避免重复初始化?

时间:2019-06-23 15:43:13

标签: swift protocols

我知道我可以使用超类来做到这一点,但是Swift不支持抽象类,我想改用协议。但是,当有很多属性要求时,我很难避免重复的self.xxx = xxx代码。示例:

protocol ManyProperties {
    var a: Int { get }
    var b: Int { get }
    var c: Int { get }
    var d: Int { get }
}

struct S: ManyProperties {
    let a: Int
    let b: Int
    let c: Int
    let d: Int

    init(a: Int, b: Int, c: Int, d: Int) {
        self.a = a
        self.b = b
        self.c = c
        self.d = d
    }
}

class C: ManyProperties {
    let a: Int
    let b: Int
    let c: Int
    let d: Int

    // duplicate initializing
    init(a: Int, b: Int, c: Int, d: Int) {
        self.a = a
        self.b = b
        self.c = c
        self.d = d
    }
}

我真的想输入类似super.init()的内容,而我不希望继承。我该怎么做?

1 个答案:

答案 0 :(得分:0)

结构有一个免费的逐成员初始化器,因此您无需为它们编写这种init

struct S: ManyProperties {
    let a, b, c, d: Int
}

但是对于班级,您可以选择:

1-使用基类并继承基类,而不遵循协议:

class ManyPropertiesClass: ManyProperties {
    let a: Int
    let b: Int
    let c: Int
    let d: Int

    // duplicate initializing
    init(a: Int, b: Int, c: Int, d: Int) {
        self.a = a
        self.b = b
        self.c = c
        self.d = d
    }
}

class C: ManyPropertiesClass {
}

2-在协议内添加init,因此它会迫使您在自动完成帮助下实现它

protocol ManyProperties: class {
    var a: Int { get }
    var b: Int { get }
    var c: Int { get }
    var d: Int { get }

    init(a: Int, b: Int, c: Int, d: Int)}
}

3-在协议内定义另一个初始化器,并使变量set可用,以便编译器知道所有属性都已初始化。然后,您可以扩展协议以使用初始化程序:

protocol ManyProperties: class {
    var a: Int { get set }
    var b: Int { get set }
    var c: Int { get set }
    var d: Int { get set }

    init()
}

extension ManyProperties {
    init(a: Int, b: Int, c: Int, d: Int) {
        self.init()
        self.a = a
        self.b = b
        self.c = c
        self.d = d
    }
}

class C: ManyProperties {
    var a: Int = 0
    var b: Int = 0
    var c: Int = 0
    var d: Int = 0

    required init() {}
}