[swift-evolution] Ability to mark a class as publicly final while remaining internally non-final

Matt Comi mattcomi at gmail.com
Mon Apr 25 22:28:25 CDT 2016


> On 25 Apr 2016, at 3:08 PM, Thorsten Seitz via swift-evolution <swift-evolution at swift.org> wrote:
> 
> I think the underlying problem is that you cannot "internally" conform to the internal protocol.
> 
> Desirable would be something like the following:
> 
> public class SomePublicClass: internal SomeInternalProtocol { // note internal conformance
>   public convenience init(someOtherParameter: Int) {
>     self.init(parameter: SomeInternalClass())
>   }
>   internal required init(parameter: SomeInternalClass) {
>       // do something
>   }
> }
> 
> i.e. when conforming internally the required init would only have to have internal visibility and you could introduce a convenience init for the public API. SomePublicClass would only be usable as SomeInternalProtocol within the module. 

I like that. So I guess, more broadly, my proposal is:

Provide a mechanism that allows a non-final class to conform to an internal protocol that has an initializer requirement without needing to expose that initializer publicly.

And to recap, my suggestion was:

- Allow a class to be marked publicly final, but internally non-final.

And yours was:

- Allow a class to “internally” conform to a protocol.

Both approaches solve the same problem. Anyone got any other thoughts? Thanks.

Matt

> Am 25. April 2016 um 08:27 schrieb Matt Comi via swift-evolution <swift-evolution at swift.org>:
> 
>> Consider a public class that conforms to an internal protocol that has an initializer requirement:
>> 
>> internal class SomeInternalClass { }
>> 
>> internal protocol SomeInternalProtocol {
>> init(parameter: SomeInternalClass)
>> }
>> 
>> public class SomePublicClass: SomeInternalProtocol {
>> // compiler error: initializer requirement ‘init(parameter:)’ can only be satisfied by a `required` initializer in non-final class ‘SomePublicClass’
>> init(parameter: SomeInternalClass) { }
>> }
>> 
>> To resolve this error, init(parameter:) must be made public required, or SomePublicClass must be made final.
>> 
>> If init(parameter:) were made public required, it would expose the module's internal structure; SomeInternalClass would need to be made public also. This makes sense, of course; if SomePublicClass is public and non-final, it may be subclassed outside the module and any subclass would need to know about init(parameter:) in order to remain conformant to SomeInternalProtocol.
>> 
>> Alternatively, If SomePublicClass were made final, it could not be subclassed outside the module and thus, SomeInternalClass would not need to be exposed, but subclassing SomePublicClass within the module would also be impossible also.
>> 
>> I propose that it should be possible to mark a class as publicly final while remaining internally non-final. This would resolve both issues: SomeInternalClass can remain internal, and SomePublicClass can be subclassed within the module.
>> _______________________________________________
>> swift-evolution mailing list
>> swift-evolution at swift.org <mailto:swift-evolution at swift.org>
>> https://lists.swift.org/mailman/listinfo/swift-evolution <https://lists.swift.org/mailman/listinfo/swift-evolution>
> _______________________________________________
> swift-evolution mailing list
> swift-evolution at swift.org
> https://lists.swift.org/mailman/listinfo/swift-evolution

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://lists.swift.org/pipermail/swift-evolution/attachments/20160426/d86d369b/attachment.html>


More information about the swift-evolution mailing list