[swift-evolution] Protected access level / multiple class/struct/protocol APIs

Dietmar Planitzer dplanitzer at q.com
Wed Mar 30 12:16:25 CDT 2016


> On Mar 29, 2016, at 18:18, Joe Groff <jgroff at apple.com> wrote:
> 
> 
>> On Mar 29, 2016, at 6:04 PM, Dietmar Planitzer via swift-evolution <swift-evolution at swift.org> wrote:
>> 
>> Well that would be true if we assume that protected would work that way. Considering that this:
>> 
>> private class A { … }
>> 
>> public class B : A { … }
>> 
>> is not allowed in Swift, I don’t see a good reason why an override of a protected method should be allowed to upgrade the access level to public. On the other hand this:
>> 
>> public class A {
>>   private func foo() {
>>       print("A")
>>   }
>> }
>> 
>> public class B : A {
>>   public override func foo() {
>>       print(“B”)
>>   }
>> }
>> 
>> happens to actually work if both A and B are defined in the same file - which is rather unexpected. I would have expected that Swift would in general not allow overrides to upgrade the inherited access level. Eg exposing semantics which is embodied in a private or protected method should require a conscisous design decision and should require the designer to introduce a separate method name which is part of the public API. The public method can then call through to the private or protected method as needed.
> 
> That would still be a toothless restriction, since a subclass could define a new method:
> 
> public class B : A {
>   public func foo_() {
>       super.foo()
>   }
> }
> 
> From an interface perspective, there's no difference between a subclass defining a new method or overriding a method that happens to be private to the base class.

If a method was marked private in the base class, then it is very likely that the name of the method, the design of its argument list and its return value did not go through the same detailed design review as if the method would have been meant to be part of the class’ interface from the start. So it’s rather unlikely that increasing the visibility in an override is good idea and in the spirit of the original writer of the private method. If on the other side I’m required to introduce a new method name if I want to make the semantics of the private method part of my public interface, then (a) it gives me an opportunity to think about what kind of interface I want to commit to and (b) it gives me stability because it doesn’t matter anymore what is going to happen over time to the name, argument list and return value of the private method since the name and signature of my public method is now decoupled from the ones of the private method.

Also, your argument would just as well apply to the scenario below since a class is a collection of methods when you look at it purely from an interface perspective:

private class A { … }

public class B : A { … }

but Swift doesn’t allow this. 


Regards,

Dietmar Planitzer


> -Joe
> 



More information about the swift-evolution mailing list