当使用默认值参数覆盖函数时,如何保持默认值与超类相同?

时间:2016-08-07 11:22:55

标签: swift function inheritance override default-value

例如,这是一个超类:

class A {
    public init(a: String = "aaaa") {
        // this class is in a framework, and the subclass use that framework.
        ......
    }
}

有没有办法编写子类并使用相同的参数init默认值覆盖a

超类位于框架内。项目使用此框架,并希望使用默认参数值覆盖函数,但似乎无法在覆盖函数中获取超类默认参数值。我可以在子类中编写另一个函数,比如检查参数是否为nil,然后使用其默认值调用超类,否则,将子类参数值传递给超类。但是我想找到一种方法来编写完全相同的函数名,这意味着覆盖超类函数。

1 个答案:

答案 0 :(得分:1)

(这个答案是最新的Swift 3)

将默认参数值放在 Conven 初始值设定项中,覆盖此便利初始化程序指向的指定初始值设定项

您可以让公共超类初始化程序使用默认参数为convenience初始化程序,该程序将用作超类和子类的初始化程序“接口”。这个便利初始化程序依次只调用fileprivate 指定的初始化程序,这是您在子类中重写的初始化程序。 E.g。

public class A {
    let a: String

    /* public initializer */
    public convenience init(a: String = "aaaa") {
        self.init(b: a)
    }

    /* "back-end" fileprivate initializer: implement initializer
       logic here, and override this initializer in subclasses */
    fileprivate init(b: String) {
        self.a = b
        print("super:", b)
    }
}

public class B: A {
    let b: String

    override fileprivate init(b: String) {
        self.b = "sub_" + b
        print("sub:", b)

        super.init(b: b)
    }
}

/* The following initializations all call the convenience initializer defined in A */
let a = A()         // prints> super: aaaa
let b = B()         // prints> sub: aaaa, super: aaaa
let c = B(a: "foo") // prints> sub: foo, super: foo

print(a.a) // aaaa
print(b.a) // aaaa
print(b.b) // sub_aaaa
print(c.a) // foo
print(c.b) // sub_foo

在这个简单的例子中,子类重写了其超类的所有指定的初始化器(这里:一个指定的初始化器),这就是为什么它的超类(这里:一个)的所有便利初始化器都可用(继承)由子类,如Language Guide - Initialization - Class Inheritance and Initialization - Automatic Initializer Inheritance中的规则2 所述。

  

规则1

     

如果你的子类没有定义任何指定的初始化器,那么它   自动继承其所有超类指定的初始化器。

     

规则2

     

如果您的子类提供了其超类的所有的实现   指定的初始化程序 - 通过按照规则1继承它们,或者通过   提供自定义实现作为其定义的一部分 - 然后它   自动继承所有超类便利初始化器。