【问题标题】:'super.init' isn't called on all paths before returning from initializer. But it's useless在从初始化程序返回之前,不会在所有路径上调用“super.init”。但是没用
【发布时间】:2021-07-18 16:15:18
【问题描述】:

我有基类

class Company {
    var list: [Employee] = []
    var name: String = ""
    func getProduct() -> Product {
        return Product(name: "Phone")
    }
    required init(_ list: [Employee], _ name: String) {
        self.list = list
        self.name = name
    }
    convenience init?(_ employee: Employee?, _ name: String) {
        if ( employee == nil || name.isEmpty) { return nil }
        if let emp = employee as? Employee {
             self.init([emp], name)
        }
        self.init(employee, name)
    }
}

继承

class FoodCompany: Company{
    var qualityCertificate: String
    required init(_ list: [Employee], _ name: String) {
        self.list = list
        self.name = name
    }
    init? (_ employee : (String?, String?), _ name: String, _ qualityCertificate: String ) {
        if (  employee.0 == nil || employee.1 == nil ) {
            return nil
        }
        if ( name.isEmpty || qualityCertificate.isEmpty) {
            return nil
        }
        self.qualityCertificate = qualityCertificate
        let fName = employee.0 as? String
        let lName = employee.1 as? String
    }
}

在失败的初始化中我有一个错误 在从初始化程序返回之前,不会在所有路径上调用“super.init”。 但是,如果我没有数据,我如何添加 super.init 调用?也许我不明白什么? 也许我需要添加不带参数的init?

【问题讨论】:

  • 你说你没有数据是什么意思?你有超类初始化器需要的listname,不是吗?如果就超类而言那是无用的数据,那么听起来你没有理由在这里使用继承。

标签: swift


【解决方案1】:

现在你要创建一个对象的子类,你必须在某处调用super

我不知道ProductEmployee 是什么,但要满足继承初始化规则,你必须写这样的东西

class Company {
    var list: [Employee] = []
    var name: String = ""
    func getProduct() -> Product {
        return Product(name: "Phone")
    }
    required init(_ list: [Employee], _ name: String) {
        self.list = list
        self.name = name
    }
    convenience init?(_ employee: Employee?, _ name: String) {
        guard let emp = employee, !name.isEmpty else { return nil }
        self.init([emp], name)
    }
}

class FoodCompany: Company {
    var qualityCertificate: String
    required init(_ list: [Employee], _ name: String) {
        self.qualityCertificate = ""
        super.init(list, name)
    }

    init?(_ employee : (String?, String?), _ name: String, _ qualityCertificate: String ) {
        if name.isEmpty || qualityCertificate.isEmpty { return nil }
        guard let fName = employee.0, let nName = employee.1 else { return nil }
        
        self.qualityCertificate = qualityCertificate
        super.init([Employee(fName: fName, nName: nName)], name)
    }
}

旁注:在 init 方法中省略参数标签不是一个好的 Swift 做法。

【讨论】:

  • 天哪,谢谢,所有的问题是我没有在所需的 init 中调用 super.init
【解决方案2】:

一旦你设置了子类的属性,你就可以调用 super.init。所以先把子类中需要的init改成

required init(_ list: [Employee], _ name: String) {
    qualityCertificate = ""
    super.init(list, name)
}

然后对于另一个初始化,我将首先使用保护语句从元组中获取值

guard let firstName = employee.0, let lastName = employee.1 else { return nil }

因为现在我们要么必须使用(非 nil)值的变量,我们可以稍后使用,否则 init 将返回 nil

然后我们可以使用这两个变量来创建一个 Emplyoee 实例并发送到 super.init

super.init([Employee(firstName, lastName)], name)

如果我们还将其他验证添加到 guard 语句中,完整的初始化将变为

init?(_ employee: (String?, String?), _ name: String, _ qualityCertificate: String) {
    guard let firstName = employee.0, let lastName = employee.1, !name.isEmpty, !qualityCertificate.isEmpty) {
        return nil
    }
    self.qualityCertificate = qualityCertificate
    super.init([Employee()], name)
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2018-11-05
    • 2015-09-01
    • 2020-12-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多