> On Jul 10, 2016, at 1:37 AM, Károly Lőrentey via swift-evolution > <swift-evolution@swift.org> wrote: > > On 2016-07-09 04:39:01 +0000, Jordan Rose via swift-evolution said: > >> I wanted to share a concrete use case that Daniel Dunbar relayed to me. He >> was working on a closed class hierarchy like the ones discussed here, where >> all of the subclasses are within a single module, but they are all public. >> The class also has a required initializer for dynamic construction, so that >> they could write something like this: >> internal struct ModelContext { /*…*/ } >> public class ModelBase { >> internal required init(context: ModelContext) { /*…*/ } >> // … >> } >> public class SimpleModel: ModelBase { >> internal required init(context: ModelContext) { /*…*/ } >> } >> public class MoreComplicatedModel: ModelBase { /*…*/ } >> // (within some other type) >> public func instantiateModelObject<Model: ModelBase>(_ type: Model) -> Model >> { >> return type.init(context: self.context) >> } >> That is, a public entry point calls a required initializer with an internal >> argument type. This is the only way to instantiate Model objects, and the >> internal context type doesn’t leak out into the public API. >> Of course, Swift doesn’t allow this. If someone outside of the module >> subclasses ModelBase, there’s no way for them to provide the >> dynamically-dispatched 'init(context:)’, because they don’t have access to >> the internal ModelContext. The author of the library has to make the >> required initializers public, and either set the ModelContext separately or >> make it public as well. Even though no one outside the module should be >> using these APIs. > > Can you remind us why does Swift need required initializers to have the same > access as the containing class?
Because without required initializers you can't do something like: let cl: MyClass.Type = ... let instance = cl.init(value: 0) where MyClass has a required init(value: Int). The issue here is that in order to be able to do this, subclasses that implement another initializer must implement this one as well - so it must be visible outside of the module if it is public. > > Having only package-internal constructors in the public base class is the > usual pattern for exporting a sealed class hierarchy in some other languages, > like Java. > > -- > Károly > @lorentey > > > _______________________________________________ > swift-evolution mailing list > swift-evolution@swift.org > https://lists.swift.org/mailman/listinfo/swift-evolution _______________________________________________ swift-evolution mailing list swift-evolution@swift.org https://lists.swift.org/mailman/listinfo/swift-evolution