Sobes.tech
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
How is the open and closed record mechanism… - sobes.tech