1

与来自超类的初始化程序相比,我正在制作一个带有额外参数的子类指定初始化程序,但是,我得到了一个错误。代码是:

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(from:)' 必须由 'Pregunta' 的子类提供

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

4

2 回答 2

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)
    }
}
于 2018-01-28T22:27:07.277 回答
1

你需要在 Pregunta 和 PregRev 中的 super.init 把 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)

    }
}
于 2018-01-28T23:12:23.377 回答