这是什么意思:“如果你能满足要求,你不必提供一个必需的初始化器的明确实现”?

问题描述:

我发现这个注意斯威夫特文档中关于初始化:这是什么意思:“如果你能满足要求,你不必提供一个必需的初始化器的明确实现”?

您没有提供一个明确的实现所需的初始化,如果你可以用一个继承初始化满足要求。

什么是“显式”实现?那么什么是“隐性”呢?

什么是“满足与继承初始值设定项的要求”是什么意思?

您能给我一个代码示例,其中我不必提供显式实现所需的初始化程序吗?

+0

做下面的两个代码示例[在我的答案](https://*.com/a/42398119/2976878)有帮助吗? – Hamish

+0

相关:https://*.com/questions/26923123/what-does-the-required-keyword-in-swift-mean。 –

这里有一个内嵌说明一个例子:

protocol JSONInitializable { // Use Encoders, but just for example 
    init(fromJSON: String) 
} 

class Foo: JSONInitializable { 
    let x: Int 

    // "required" is necessary because this init is required for the 
    // conformance to JSONInitializable 
    required init(fromJSON json: String) { 
     //... 
     x = 123 //some value from the JSON 
    } 
} 

class Baz: Foo { 
    // `init(fromJSON json: String)` can be inherited, 
    // so it's implicitly defined for Baz, as well as Foo. 
} 

class Bar: Foo { 
    // The presence of this uninitialized constant `y` requires an 
    // a value in the declaration, or an initializer that sets it 
    let y: Int 

    // Since we didn't specify a value for `y` in its declaration, 
    // this initializer must be explicitly specified so as to initialize `y`. 
    // Doing so blocks the inheritance of `init(fromJSON json: String)` from 
    // the super class, and requires us to define it ourselves, 
    // in order to preserve conformance to `JSONInitializable` 
    required init(fromJSON json: String) { 
     //... 
     y = 0 
     super.init(fromJSON: json) 
    } 
} 
+0

在'Bar'类中,'y'的存在并不妨碍'init'方法的继承。未初始化的“y”的存在要求您初始化它。它可以在声明中直接初始化,或者通过'Bar'的'init'方法初始化。你可以在'Bar'中添加另一个'init'来初始化'y',但是添加另一个'init'将会阻止基类'init'方法的自动继承。所以现在你需要添加一个需要的'init'的显式实现。同样,简单地将'let y:Int'改为'let y = 0'就不需要在'Bar'中添加明确的'init'。 – rmaddy

+0

@rmaddy谢谢。当我写下“y的存在防止...”时,我想到了这一点,但我并不十分清楚。我会更新我的答案以反映您的澄清 – Alexander

+0

您的澄清仍然不正确。 y的存在(初始化或不初始化)对初始化程序是否隐式地从基类继承是没有影响的。这是两个不同的问题。 1.存在未初始化的“y”需要初始化。这可以在声明上或通过'init'。 2.一旦将一个'init'添加到类中,则不会自动继承基类初始化程序。 – rmaddy

它是这样说:如果你已经为你声明它们初始化所有的属性,没有必要写一个初始化。

通常,当你有属性声明并没有设置,你写的init()方法,并设定他们那里,如果有父类所需的初始化,你叫

super.init(possible, arg: anotherArg) 

既然你不不需要设置任何东西,也不需要写任何东西,并且由于班级中没有init,所以超级通话将自动发生。 (当然,如果所需的init需要传入值,您仍然需要提供它们。)那么如何实现? (见下文)。底线是大部分工作都是为你完成的。但是,一旦你写了一个init(),那么你就会带走这种自动行为,并且你必须确保这些“自动”调用是明确做出的。

最后,在我提供一个例子,我要解决这个说法:

“如果你能继承初始化满足要求”如果家长没有一个不带参数的初始化器,它将如何获得这些参数?在这种情况下,你需要用正确的参数来初始化你的类。

这里是未在IB建立一个视图控制器的一个例子,我会用超级的需要初始化正常创建它,因为我没有写一个初始化为我的派生类:

让利VC = MagicController(nibName:无,捆绑:无)

import UIKit 
import Dotzu 

class MagicController: UIViewController, UIGestureRecognizerDelegate { 
    let action = #selector(MagicController.buttonTapped(_:)) 
    let action2 = #selector(MagicController.secondButtonTapped(_:)) 
    let mainAction = #selector(MagicController.mainButtonTapped(_:)) 

    let defaultPalette = Palette.randomPalette() 
    var questions = [Question]() 
    var startTime = TimeInterval() 
    var endTime = TimeInterval() 
    var selectedTimeIndex = 0 
    var selectedTagIndex = 0 
    var selectedRatingIndex = 0 
    var selectedTag = "swift" 
    let timeSpanDropDown = DropDown() 
    let ratingDropDown = DropDown() 
    let tagDropDown = DropDown() 
    var pageNumber = 1 
    var savedIndex = 0 
    var savedPostId = -1 
    var quotaCount = -1 
    var isFirstTime = true 

    let queryFactory = Queries(client: APIClient()) 

    var timeSpanButton = UIBarButtonItem() 
    var ratingButton = UIBarButtonItem() 
    var tagButton = UIBarButtonItem() 
    var dbButton = UIBarButtonItem() // 


/// start the console log, configure the main view's buttons/actions and present the UI 
    override func viewDidLoad() { 
     super.viewDidLoad() 
     Dotzu.sharedManager.enable() 
     self.edgesForExtendedLayout = [] 
     configureButtons(container: view) 
     view.setNeedsLayout() 
    } 

    ///configure the buttons/actions, prepare and present the UI 
    /// The first time this is called it sets up the buttons and drop downs 
    /// cleanupDataSource() has no effect the first time it is called 
    /// - Parameter animated: passed to super 
    override func viewWillAppear(_ animated: Bool) { 
      super.viewWillAppear(animated) 
      if isFirstTime { 
       isFirstTime = false 
       initializeButtons() 
       setupDropDowns() 
      } 
      cleanupDataSource() 
     } 
/// etc. 
} 

正如你所看到的,我没有写这个视图控制器一个init,即使视图控制器都需要有一个初始化。我使用init()甚至在我的代码中都没有初始化我的视图控制器。