swift 为什么要写required init(){}?

aydmsdu9  于 2023-05-27  发布在  Swift
关注(0)|答案(1)|浏览(148)

我不明白为什么会出现编译器错误:
使用元类型值构造类类型“Self”的对象必须使用“required”初始化器

下面是完整的代码。

class ParentFactory {
    static func create() -> Self {
        return self.init()
    }
    
//    required init(){}
    
    func printMessage() {
        print("Super")
    }
}

class Child1Factory: ParentFactory {
    override func printMessage() {
        print("1 Class")
    }
}

class Child2Factory: ParentFactory {
    override func printMessage() {
        print("2 Class")
    }
}

class Factory {
    static func createFactory(_ type: String) -> ParentFactory {
        if type == "1" {
            return Child1Factory.create()
        } else {
            return Child2Factory.create()
        }
    }
}

如果我写required init() {},错误不会发生。我不明白为什么我需要required init,即使它在初始化器中没有任何代码。

tquggr8v

tquggr8v1#

Swift文档
Swift提供了一个 default initializer 给任何结构体或类,它为所有属性提供了默认值,并且本身不提供至少一个初始化器。默认初始化器只是创建一个新示例,并将其所有属性设置为默认值。
您的ParentFactory没有存储属性,因此,理论上,将创建默认初始化程序,并且应该足够了。但是,您已经使用了 meta类型Self,所以您不一定要示例化ParentFactory-它可以是ParentFactory的子类,实际上这就是您正在做的事情。
现在,想象一下如果Child1Factory看起来像这样:

class Child1Factory: ParentFactory {
    let aProperty: Int
    
    init(number: Int) {
        self.aProperty = number
        super.init()
    }

    override func printMessage() {
        print("1 Class")
    }
}

这是一个完全有效的实现--我们有一个初始化类属性的初始化器,它调用超类初始化器。但是,我不能说let child = Child1Factory()-初始化器不存在,但这正是当您调用Child1Factory.create并执行Self.init()时所做的事情。
为了防止这种情况,你的父类必须有一个与Self init签名匹配的init --这样就可以保证这个类和所有子类都有一个带有该签名的init
初始化器是否为空并不重要。重要的是你要确保所有的子类都可以用初始化器签名来调用。

相关问题