这意味着什么:“如果能满足要求,您不必提供所需初始化程序的显式实现”?

时间:2017-07-07 16:15:20

标签: swift initialization

我在Swift文档中找到了关于初始值设定项的说明:

  

如果可以使用继承的初始化程序满足要求,则不必提供所需初始化程序的显式实现。

什么是“明确”实施?什么是“隐含的”呢?

“满足继承初始化程序的要求”是什么意思?

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

2 个答案:

答案 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()初始化了我的视图控制器,甚至不在我的代码中。