Everything you need to know about Swift Access Modifiers
--
Swift 4 provides five different access levels. There are always some methods or variables in Object Oriented Programming that should be private or final. This enables you to hide the implementation details of your code which is the main purpose of these keywords:
open
Open is the least restrictive access level. It enables an entity to be used outside the defining module (target) and it can be subclassed or overridden from any module that imports the module where they’re defined. This is why you can override or subclass UITableView
when you import it from UIKit
.
public
Like open access level, public access level enables an entity to be used outside the defining module (target). But open access level allows us to subclass it from another module where in public access level, we can only subclass or override it from within the module it is defined. The public
defined entity can be subclassed or overridden only within the module where they’re defined.
open vs. public
// First.framework – A.swift
open class A {}// First.framework – B.swift
public class B: A {} // ok// Second.framework – C.swift
import First
class C: A {} // ok// Second.framework – D.swift
import First
class D: B {} // error: B cannot be subclassed
A class defined as open
can be subclassed from other modules. Also, they allow members from other modules to use and override them. public
allows classes from other module to use them, but not to inherit them. Also, they allow members from other modules to use them, but not to override them.
internal
An internal
defined can be accessed anywhere within the same module (target) they are defined but not from anywhere outside. It is good to know that this is the default access level.
// First.framework – A.swift
internal struct A {}
// First.framework – B.swift
A() // ok
// Second.framework – C.swift
import First
A() // error: A is unavailable
This is very helpful when your developing a library (framework), you can use internal
to hide library structure and provide interfaces for users.
fileprivate
Restricts the use of an entity to its defining source file.
private
Private access restricts the use of an entity to the enclosing declaration, and to extensions of that declaration that are in the same file.
final
As of Swift 3 you can add final
to any access level, except open
(since open
is for providing overriding and subclassing access), to prevent subclassing or overriding of a class method or property.
Swift 4, extensions, and a new private access
Swift 4 has changed the scope of private access reducing the need to use fileprivate
for extension access.
Before swift 4, private access level didn’t allow the use of a class member inside the extension of same class:
class A {
private var flag = false
}extension A {
func isFlagSet() -> Bool {
return flag
// Error in Swift 3
// works fine in Swift 4
}
}
In Swift 3 the problem is that the private
access level restricts access to the property to the enclosing class declaration. The extension is not allowed access even though it is in the same source file. The solution is to switch the access level to fileprivate
.
Swift 4 lets us to use private
access to include extensions which reduce use of fileprivate
for properties that are being accessed within the extensions.
Recap
public
is accessible (only accessible, no option for subclassing/overriding) outside the defining module. open
however offers both accessibility and overridability even outside its module. internal
is not even accessible outside its own module. fileprivate
allows use only within the defining source file while private
allows use only from the enclosing declaration and new in Swift 4, to any extensions of that declaration in the same source file.
Further Study
Access Control and protected
Access Control
Does Swift have access modifiers?