[swift-evolution] [swift-evolution-announce] [Review] SE-0117: Default classes to be non-subclassable publicly

Károly Lőrentey karoly at lorentey.hu
Sat Jul 9 18:37:45 CDT 2016


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?

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




More information about the swift-evolution mailing list