Swift 如何声明子类指定的初始值设定项,其参数比超类多?

Swift 如何声明子类指定的初始值设定项,其参数比超类多?,swift,designated-initializer,Swift,Designated Initializer,我正在创建一个子类指定的初始值设定项,与来自超类的初始值设定项相比,它有一个额外的参数,但是,我得到了一个错误。代码是: class Pregunta: Codable { var codImagen: String var respCorrecta: Int var respUsuario = -1 init(codImagen:String, respCorrecta:Int){ self.codImagen = codImagen

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

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
    }
}
我得到了错误

“必需的”初始值设定项“init(from:)”必须由“Pregunta”的子类提供


有什么问题吗?我读到我必须使用super.init和超类初始值设定项。提前感谢。

这与您的
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)
    }
}

这与
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)
    }
}

在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)

    }
}

在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)

    }
}

我如何实现该功能?使用POP(面向协议的编程)方法会简化我的代码吗?我如何实现?使用POP(面向协议的编程)方法会简化我的代码吗?谢谢你的关注。事实上,作为一名新手,我一直在努力实现init(from:),所以我决定简单地创建两个类,而不是使用iheritance。这不是最优的,但它是有效的。:)现在看,Swift团队站在你这边,但我认为他们做不了什么。您刚刚碰到了语言让您失望的地方。我编辑了我的答案,添加了
init(from:)
的实际实现。你试图写这篇文章,所以你应该得到更多的帮助。:)工作起来很有魅力。谢谢你友好的回复:)谢谢你的关心。事实上,作为一名新手,我一直在努力实现init(from:),所以我决定简单地创建两个类,而不是使用iheritance。这不是最优的,但它是有效的。:)现在看,Swift团队站在你这边,但我认为他们做不了什么。您刚刚碰到了语言让您失望的地方。我编辑了我的答案,添加了
init(from:)
的实际实现。你试图写这篇文章,所以你应该得到更多的帮助。:)工作起来很有魅力。感谢您的友好回复:)