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

Dietmar Planitzer dplanitzer at q.com
Tue Mar 29 20:04:08 CDT 2016


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.

Anyway, I do think that a protected access level would be a useful tool to have exactly because it would allow me to clearly communicated the intent of whether a method is only there for use by subclassers. Today I can’t do that and thus I have to mark the method as public and thus make it part of the overall class API which means that I end up making a much bigger promise than I actually intended to give.


Regards,

Dietmar Planitzer



> On Mar 29, 2016, at 16:56, Howard Lovatt via swift-evolution <swift-evolution at swift.org> wrote:
> 
> I tend to think an intended use annotation that could also be used in Obj-C would be better than protected. The problem with protected is that it provides virtually no protection at all; you can trivially expose it in a derived class, e.g.:
> 
> class Protected {
> protected func onlyDerived() { ... }
> }
> 
> class Derived: Protected {
> public override func onlyDerived() { super.onlyDerived() }
> }
> 
> let d = Derived()
> d.onlyDerived() // Protection lost
> 
> Therefore an annotation would be just as effective.
> 
>   -- Howard.
> 
> On 29 March 2016 at 21:54, Andrey Tarantsov via swift-evolution <swift-evolution at swift.org> wrote:
> 
> > Imho it would be nice to be able to mark a method that is only there to be overridden and should never be called directly, but I don't think the compiler has to enforce this:
> > An official way to document the intent that affects autocompletion would be sufficient for me.
> 
> An interesting idea that I see reflected in another proposal (intendedusage doc tag, or something like that).
> 
> Why, though? If we can express it, why not also make it a part of the signature and get warnings/errors on violations?
> 
> I have an argument in favor of annotations:
> 
> + The documentation is known to lie and to get out of date, even when acting on best intentions. I know mine did, and I'm writing a lot less of it now. So I also see compiler-enforced annotations as “more reliable documentation”.
> 
> What are other possible arguments for and against?
> 
> > - callable (read for properties)
> > - can override, call to super enforced
> > - can override
> > - has to be overridden (abstract)
> > - properties only: Write access
> 
> You're right, perhaps this isn't so much about access as it is about intended usage. (Not sure what that distinction means in practice, though.)
> 
> A.
> _______________________________________________
> swift-evolution mailing list
> swift-evolution at swift.org
> 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



More information about the swift-evolution mailing list