[swift-evolution] [Proposal] Protected Access Level
Xiaodi Wu
xiaodi.wu at gmail.com
Sat May 28 18:10:25 CDT 2016
Seems entirely reasonable to me. POP aficionados may object, but I think
the pros and cons of this type of access are well trodden terrain and I
think it's a net win to have this available in Swift going forward.
On Sat, May 28, 2016 at 18:53 Vanderlei Martinelli via swift-evolution <
swift-evolution at swift.org> wrote:
> Hello.
>
>
> This is the first draft. I'd like to know your opinion about it.
>
> (I know that this subject could have been discussed before. If so, please
> indicate me the correct thread to follow and interact.)
>
>
> Regards,
>
> Vanderlei Martinelli
>
>
> ---
>
>
> Introduction
>
> Protected access level will enable entities to be used within the
> container type and by derived types only.
> Motivation
>
> Today Swift has three access levels (public, internal and private), but
> lacks a way to describe a member that can be only visible to its type or
> derived types.
>
> A common case is the UIView from UIKit. Many developers are tempted to
> make this call:
>
> view.layoutSubviews()
>
> The documentation says: "You should not call this method directly. If you
> want to force a layout update, call the setNeedsLayoutmethod instead to
> do so prior to the next drawing update. If you want to update the layout of
> your views immediately, call the layoutIfNeeded method."
>
> But yes, you should call this method directly if you are subclassing the
> view and needs to perform additional layout to its subviews ("subclasses
> can override this method as needed"):
>
> public override func layoutSubviews() {
> // We are calling the super method directly here.
> super.layoutSubviews()
>
> // Do more adjustments to this view's subviews...}
>
> So, yes, we can call this method directly when subclassing, but the Swift
> compiler will not prevent you from do this when not subclassing or from any
> other foreign class. It will not even issue a warning.
>
> In Objective-C problems like this are usually "solved" my adding a kind of
> "protected" header (.h) that is intended to be included only when the
> developer is subclassing. In Swift we do not have headers, but we have the
> new access level model. So, if the declaration of this method was...
>
> protected func layoutSubviews()
>
> ... no one outside the class or derived classes would be allowed to call
> this method directly.
>
> Of course, there are other cases in the Cocoa frameworks and there are
> many other cases when we are developing software in Swift that the
> protected access level would be very usefull.
> Proposed solution
>
> Create the protected access level.
> Detailed designReference Types (classes)
>
> When declarated by a class the protected member will be visible to the
> class itself and all the derived classes.
>
> // BaseClass.swiftpublic class BaseClass {
> public protected(set) var x = 20
> protected let y = 10
>
> protected func doSomething() {
> // ...
> }}
> // DerivedClass.swiftpublic class DerivedClass: BaseClass {
> protected override doSomething() {
> self.x = 10 * self.y
> }}
>
> If the member is declared as final then it will be visible but not can be
> overrided by the derived classes. Just like it works with other access
> levels.
> Value Types (structs, enums, etc.)
>
> Value types cannot have derived types. In this case the protected access
> level does not make sense and will not be allowed in their members.
> Protocols
>
> Protocols do not declare access level for their members. So the protected access
> level is not applicable here.
> Extensions
>
> Extensions will not be able do be protected nor their members.
> Special Note
>
> The protected access level can only be applied to classes, structs and
> other types when nested inside other type. So the following code will not
> compile:
>
> // ERROR: A first level class cannot be protected.
> protected class MyProtectedClass {
> /// ...}
>
> But nested declarations will be allowed, so this code will compile:
>
> // We can declare a protected class (or struct, enum, etc.) if// and only if they are nested inside other type.public class MyPublicClass {
> protected class MyProtectedClass {
> /// ...
> }}
> // Since `MyProtectedClass` is nested and protected we// can have access to it here.public class MyDerivedClass: MyPublicClass {
> public func doSomething() {
> let c = MyProtectedClass()
>
> /// ...
> }}
>
> Impact on existing code
>
> The imported Cocoa frameworks may have annotations on the "Objective-C
> side" that will inform if one member is protected. If this will be case
> (for the layoutSubviews method, as example), only code accessing these
> now protected members outside the owner class and its derived classes will
> have to change (currently this can be considered an error, anyway).
>
> Any other code will be not impacted by this feature as it is new to the
> language.
> Alternatives considered
>
> Do not add the protected access level to the current model.
>
>
> ---
>
>
>
>
> _______________________________________________
> 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/20160528/80b408c4/attachment.html>
More information about the swift-evolution
mailing list