There has been much said about protected
and how Swift needs, I mean, NEEDS, the "protected" keyword. In fact, there has been so much ruckus about it that the Swift team wrote a blog entry on it: Access Control and protected
.
While I whole heartedly agree that the protected
keyword is a terrible idea from an inheritance perspective, the intent of the notion has great value. I'm going to define the intent as this:
The ability to separate concerns of implementors and consumers.
: .callout
If we focus the definition, it's really not that hard to image how we can extend the existing public
, internal, and private
access modifiers that Swift already offers with a fourth option: protected
.
I propose that we could enable the following:
- Introduce the
protected
keyword - Modify the
import
rules to include aprotected
modifier
The rule for the protected
keyword would be quite simple:
Protected access enables entities to be used within any source file from their defining module, and also in a source file from another module that imports the defining module with the
protected
modifier. You typically use protected access to specify the public interface for those wishing to extend the functionality of your types, but hiding that functionality from the consumers of your API.
: .callout
An example would be this:
Defined in module FooMod
public struct Foo {
public func foo() {}
protected func bar() {}
public var fizzy: Int
protected var fuzzy: Int
}
protected func MakeSuperFoo() -\> Foo {}
Then, in another module, you would have to use the following in order to gain access to the protected
members.
import FooMod // Brings in all of the public members
import protected FooMod // Brings in all of the protected members
let f: Foo = MakeSuperFoo()
f.foo()
f.bar()
I think this fits into the existing access control mechanism perfectly and provides a way to provide the high-level intent of what people are asking for with protected
.