Middle+
How is the open and closed record mechanism implemented in Swift?
sobes.tech AI
Answer from AI
In Swift, the mechanism of open and closed access levels is implemented using the keywords open and public for access outside the module, as well as final to prevent inheritance and overriding.
open: Allows a class or class member (method, property, etc.) to be inherited and overridden outside the module where they are defined. This is the least restrictive level.public: Allows a class or class member to be accessible outside the module, but does not permit inheritance or overriding outside this module.final: Can be applied to a class, method, or property.- When applied to a class: prevents inheritance of this class.
- When applied to a method or property: prevents it from being overridden in subclasses.
Thus, "open" entities can be considered as those defined with open, allowing broad interaction outside (inheritance, overriding). "Closed" entities can be represented by those with final (completely closed from inheritance/overriding) or public (accessible but cannot be inherited/overridden outside the module).
Example:
// Module A
open class OpenClass {
open func openMethod() {
// Can be overridden outside the module
}
public var publicProperty: Int = 0 // Accessible outside the module, but property cannot be overridden as a stored property
}
public class PublicClass {
public func publicMethod() {
// Accessible outside the module, but method cannot be overridden outside the module
}
internal func internalMethod() {
// Accessible only within the module
}
}
final class FinalClass {
// Cannot be inherited
}
extension PublicClass {
// Extensions within the module are allowed
}
// Module B (uses Module A)
import ModuleA
class SubclassedOpenClass: OpenClass {
override func openMethod() {
// Can override
}
}
let openInstance = OpenClass()
openInstance.openMethod() // Accessible
let publicInstance = PublicClass()
publicInstance.publicMethod() // Accessible
// let subclassedPublic = PublicClass() // Error: PublicClass cannot be inherited outside the module
// let finalInstance = FinalClass() // Error: FinalClass cannot be instantiated directly outside the module if its initializer is not accessible
// let _ = publicInstance.internalMethod() // Error: internalMethod is not accessible outside the module
// Extension of PublicClass outside the module is generally not allowed,
// except in specific scenarios such as extending a Protocol.
Table summarizing access levels:
| Access Level | Description | Accessible from | Inherited outside module? | Overridden outside module? |
|---|---|---|---|---|
open |
Least restrictive | Entire module + Outside module | Yes | Yes |
public |
Accessible outside, but not for inheritance/overriding | Entire module + Outside module | No | No |
internal |
Default | Entire module | No | No |
fileprivate |
Only within the file | Only within the file | No | No |
private |
Only within the declaration (class, struct, etc.) | Only within the declaration | No | No |