如何使用比超类更多的参数声明子类指定的初始化器?

时间:2018-01-28 22:20:35

标签: swift designated-initializer

我正在创建一个子类指定初始值设定项,其中一个额外的参数与超类中的初始值设定项相比,但是,我得到一个错误。代码是:

class Pregunta: Codable {
    var codImagen: String
    var respCorrecta: Int
    var respUsuario = -1

    init(codImagen:String, respCorrecta:Int){
        self.codImagen = codImagen
        self.respCorrecta = respCorrecta
    }
}

class PregRev: Pregunta {
    var codAyuda: String

    init(codImagen:String, respCorrecta:Int, codAyuda: String){
        super.init(codImagen: codImagen, respCorrecta: respCorrecta)
        self.codAyuda = codAyuda
    }
}

我收到错误

  

'required'初始化'init(来自:)'必须由'Pregunta'的子类提供

有什么问题?我读到我只需要使用带有超类初始化程序的super.init。提前谢谢。

2 个答案:

答案 0 :(得分:3)

这与init(codImagen:String, respCorrecta:Int, codAyuda: String)的实现无关(尽管该实现实际上是错误的)。它与您的超类采用Codable这一事实有关。

Codable需要init(from:)的实施。您的超类通过协议扩展继承了这一点,因此您没有提供实现这一事实没有问题。

但子类是另一个故事。通过在子类中创建指定的初始化程序,您已经杀死了继承。因此,您的子类不会从超类继承init(from:)的实现。因此,您必须在子类中明确提供它:

class Pregunta: Codable {
    var codImagen: String
    var respCorrecta: Int
    var respUsuario = -1

    init(codImagen:String, respCorrecta:Int){
        self.codImagen = codImagen
        self.respCorrecta = respCorrecta
    }
}

class PregRev: Pregunta {
    var codAyuda: String
    enum CodingKeys : String, CodingKey {
        case codAyuda
    }
    init(codImagen:String, respCorrecta:Int, codAyuda: String){
        self.codAyuda = codAyuda
        super.init(codImagen: codImagen, respCorrecta: respCorrecta)
    }
    required init(from decoder: Decoder) throws {
        let con = try decoder.container(keyedBy: CodingKeys.self)
        self.codAyuda = try con.decode(String.self, forKey: .codAyuda)
        try super.init(from:decoder)
    }
}

答案 1 :(得分:1)

你需要super.init在Pregunta和PregRev中将self.codAyuda = codAyuda放在super.init之前

class PregRev: Pregunta {
    var codAyuda: String

    init(codImagen:String, respCorrecta:Int, codAyuda: String){
        self.codAyuda = codAyuda
        super.init(codImagen: codImagen, respCorrecta: respCorrecta)

    }
}