You Really Don't Need Protected Members

When Swift's access controls were introduced I wrote about how they worked like C's with good use of internal and external headers. I've recently been asked about how to do access private properties when subclassing and thought it would be worth sharing the conversation.

If you are new to Swift's access controls I suggest you look at the previous post (same link as above) first as this is the refinement and conclusion (in my mind) of an issue that I an open question when I wrote that. If you are new to programming then this post is probably one to skip as it is more about comparing how things can be done in Swift that people are used to doing a certain way in Java than something meant as an introduction to the concepts.

I’ve a question in context of open/closed principle (Software entitles should be open for extension but closed for modification.), coming from Java, AS3 background highly influenced by the Design Patterns book by the Gang of Four, the way I see protected is so that work can be extended by other people. 

How can I fully extend a class in it’s entirety without access to it’s private members, surely I can override methods but that won’t be enough.

The only way I could think is to approach this by declaring everything public or have a getter setter for each but then I’m violating “Encapsulation” principle
The short version is I would design the system in such a way to avoid requiring any inheritance apart from the specifically designed to inherit from system classes (NSObject, UIView, UIViewController etc.).
It has been a while since I read GoF and my recent code has been much more influenced by the functional school. Immutable over mutable. Structs over objects. If objects are used prefer composition and encapsulation to inheritance. Use protocols to separate the components and allow dependency injection for testing and substitutability.

In my opinion you shouldn't be inheriting from classes not explicitly designed for it. Anything changing private members is very much inside the class and you are exceedingly strongly coupled to parent class implementation details. I'm increasingly dissatisfied with (implementation) inheritance generally and there are usually alternatives such as the delegate pattern (pretty sure that is in GoF too) commonly used in the Cocoa frameworks. 

I don't see good reasons why properties that can be safely manipulated by subclasses can't be safely manipulated by other code and if there was a protected category that would only serve to force people to subclass if they ever wanted to change those properties.
Thanks Joseph for your answer and a different light, sure composition is better than inheritance, but even then in context of this case where super class needs to have one of it’s private property to be set by the inherited class, whether using inheritance or composition both needs to be set.

Well in the meantime I put myself in other people shoes who’d be extending classes and noticed that if they need to change some private property of the parent class (parent is dependent on this), I’d provide a public interface/func for that while keeping the var private, that solves the problem, and I’m kinda starting to see that I can live without protected.

However, if and ever the need arise which shouldn't, I think the mix and match of extensions and composition/inheritance would do the job.
If it needs to be set it should be public. Protected is only advisory anyway because you can always subclass and expose if necessary. You need to decide if the property is part of the public interface or not. You shouldn't force inheritance on consumers of your API.

Get Some of the Benefits of Protected with a Protocol

One option for your own classes is to define a protocol that exposes the functions and properties that will generally be used by external clients but have the class expose the implementation detail properties that you might need to tweak in a subclass or in customising the behaviour of an encapsulated class or in a factory function. This way you can store the object as the protocol type and only have access to the really public elements with appropriate code completion.

* This conversation has been reformatted and lightly edited slightly from the original email conversation to make for a better blog post.