3.5 Software Engineering with Access Modifiers
As we’ve mentioned, Swift’s public, internal and private access modifiers work differently than access modifiers in languages like Java, C# and C++. In Swift, they are scope based, rather than type based. In this section, we discuss Swift’s access modifiers in more detail and provide guidelines for using them.
Files and Modules
In Swift, groups of related files are compiled into a module. For example, the source-code files that implement an app are defined in an app project and compiled into a single module. Similarly, you can define the files for related reusable software components in a framework project and those files, too, will be compiled into a module. Modules can be imported into other projects for reuse, just as we did with the Foundation framework in Section 3.3.
Access Modifiers Can Be Applied to Many Swift Code Elements
Swift’s access modifiers enable you to restrict access to various code elements based on the source-code file or module in which those elements are defined. For example:
- You can declare a function private so it can be used only in its defining file.
- You can declare a function internal so it can be used only in the module in which it’s defined—internal is also the default access modifier if you don’t explicitly provide one.
- You can declare a function public so it can be used in its defining module and in any module that imports the defining module.
These concepts apply to every language element that can be defined at the top level of a source-code file, such as variables, constants, classes, functions and other language elements that you’ll see in later chapters.
Access Modifiers in a Class
Even a class’s members are accessible as we described above. If you define a private class member in Java, C# or C++, that member is known only within its defining class. In Swift, however, a private class member can be accessed by the class’s other members and in any other Swift code defined in the same source-code file. To prevent any code outside a class from accessing the class’s private members—and to get the benefit of what private offers in languages such as Java, C# and C++—you must define the class in a file by itself. Doing so enables you to enforce encapsulation—that is, to hide the class’s implementation details from the other source code in your module and any module into which your module is imported. For example, for this chapter’s Account class, defining the class in its own file enabled us to ensure that client code could not access the balance property’s private setter.
Access Modifier Resources
For more information on access modifiers, see the Swift blog post on Access Control:
and The Swift Programming Language book’s Access Control chapter: