我在Swift文档中找到了关于初始值设定项的说明:
如果可以使用继承的初始化程序满足要求,则不必提供所需初始化程序的显式实现。
什么是“明确”实施?什么是“隐含的”呢?
“满足继承初始化程序的要求”是什么意思?
你能给我一个代码示例,我不需要提供所需初始化程序的显式实现吗?
答案 0 :(得分:0)
这是一个内联解释的例子:
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)
}
}
答案 1 :(得分:0)
这是这样说的:如果您在声明它们时初始化了所有属性,则无需编写初始化程序。
通常,当您声明属性而未设置属性时,您编写一个init()方法并将其设置在那里,如果父类中有必需的初始值设定项,则调用
from django.utils.deprecation import MiddlewareMixin
class CheckPageAccessMiddleware(MiddlewareMixin):
def process_request(self, request):
if not request.user.is_authenticated():
current_page_url = request.path_info.lstrip('/')
ignore_list = config('PAGE_RESTRICT_PAGE_IGNORES', cast=lambda v: [s.strip() for s in v.split(',')])
#if not current_page_url or not any(current_page_url != url for url in ignore_list):
if not current_page_url in ignore_list:
# first things first ...
if not has_attr(request, 'pages_visited'):
request.pages_visited = set()
if not has_attr(request, 'page_count'):
request.page_count = 0
if current_page_url not in request.pages_visited:
request.pages_visited.add(current_page_url)
request.page_count += 1
if request.page_count > config('PAGE_RESTRICT_PAGE_LIMIT'):
return HttpResponseRedirect(config('PAGE_RESTRICT_REDIRECT_URL'))
由于您不需要设置任何内容,因此您无需编写任何内容,并且由于您的课程中没有init,因此超级调用将自动发生。 (当然,如果所需的init需要传入值,你仍然需要提供它们。)那么如何实现呢? (见下文。)最重要的是,大部分工作都是为你完成的。
但是,一旦你编写一个init(),那么你就会消除这种自动行为,你必须确保明确地进行那些“自动”调用。
最后,在我提供一个例子之前,我应该解决这个问题:
“如果您可以使用继承的初始化程序来满足要求”
如果父级没有不带参数的初始化器,它将如何获得这些参数?在这种情况下,您需要使用正确的参数使用所需的超级init初始化您的类。
这是一个未在IB中设置的视图控制器的示例,我通常会使用super的必需初始化程序创建它,因为我没有为我的派生类编写初始化程序:
让vc = MagicController(nibName:nil,bundle:nil)
super.init(possible, arg: anotherArg)
正如您所看到的,即使视图控制器具有必需的init,我也没有为此视图控制器编写init。我使用init()初始化了我的视图控制器,甚至不在我的代码中。