Swift 3 brought many new features and enhancements to the language. It also introduced several changes to access control by adding two new access levels, open and fileprivate. I already discussed the difference between private and fileprivate earlier this year. In this tutorial, I focus on the difference between public and open.
Public and Private
Like private and fileprivate, the public and open access levels have several things in common. Entities that are declared public or open are accessible from the module in which they are defined and from any module that imports the module they are defined in. That makes sense. Right?
What Is the Difference
The difference between public and access is subtle but important. The open access level was introduced to impose limitations on class inheritance in Swift. This means that the open access level can only be applied to classes and class members, such as properties and methods.
The idea is simple. An open class can be subclassed in the module it is defined in and in modules that import the module in which the class is defined. The same applies to class members. An open method can be overridden by subclasses in the module it is defined in and in modules that import the module in which the method is defined.
This sounds very much like the public access level. That is true for Swift 2. The meaning of the public access level has changed slightly. Classes that are declared public can only be subclassed in the module they are defined in. The same applies to public class members, which can only be overridden by subclasses defined in the module they are defined in.
Why Is This Necessary
The public and open access levels add an additional layer of access control. Some classes of libraries and frameworks are not designed to be subclassed and doing so may result in unexpected behavior.
The Core Data framework is a fine example. The documentation clearly states that some methods of the NSManagedObject
class should not be overridden. If Apple were to apply the public access level to these methods, developers would no longer be able to override these methods in their NSManagedObject
subclasses. That is what the public and open access levels are designed for. They protect the integrity of a library or framework.
If a class or class member is marked as open, the maintainer of the library or framework communicates to developers that it is fine to subclass or override the class or class member. That is a very useful statement if you ask me.
What Are the Consequences
Before the introduction of the open access level, the public access level was the least restrictive access level. This is no longer true for classes and class members. This means that libraries and frameworks need to be updated for Swift 3.
Why is that? Public classes and class members are still accessible by other modules. Great. But public classes can no longer be subclassed and public class members can no longer be overridden. This can dramatically decrease the usefulness of several libraries and frameworks.
More Transparency
If you maintain a library or framework, the addition of the open access level is an interesting exercise. You are forced to decide whether the classes of your library or framework should be subclassable. And the same applies to class members.