这是什么意思:“如果你能满足要求,你不必提供一个必需的初始化器的明确实现”?
我发现这个注意斯威夫特文档中关于初始化:这是什么意思:“如果你能满足要求,你不必提供一个必需的初始化器的明确实现”?
您没有提供一个明确的实现所需的初始化,如果你可以用一个继承初始化满足要求。
什么是“显式”实现?那么什么是“隐性”呢?
什么是“满足与继承初始值设定项的要求”是什么意思?
您能给我一个代码示例,其中我不必提供显式实现所需的初始化程序吗?
这里有一个内嵌说明一个例子:
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)
}
}
在'Bar'类中,'y'的存在并不妨碍'init'方法的继承。未初始化的“y”的存在要求您初始化它。它可以在声明中直接初始化,或者通过'Bar'的'init'方法初始化。你可以在'Bar'中添加另一个'init'来初始化'y',但是添加另一个'init'将会阻止基类'init'方法的自动继承。所以现在你需要添加一个需要的'init'的显式实现。同样,简单地将'let y:Int'改为'let y = 0'就不需要在'Bar'中添加明确的'init'。 – rmaddy
@rmaddy谢谢。当我写下“y的存在防止...”时,我想到了这一点,但我并不十分清楚。我会更新我的答案以反映您的澄清 – Alexander
您的澄清仍然不正确。 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()甚至在我的代码中都没有初始化我的视图控制器。
做下面的两个代码示例[在我的答案](https://stackoverflow.com/a/42398119/2976878)有帮助吗? – Hamish
相关:https://stackoverflow.com/questions/26923123/what-does-the-required-keyword-in-swift-mean。 –