Effective Kotlin: Item 15 — Minimize the accessibility of classes and members
If you are writing APIs item 15 of Effective Java by Joshua Bloch is hugely important. The principle is simple, “make each class or member as inaccessible as possible” to hide the internals, and dependencies, of your classes.
The developers of Kotlin took the opportunity to improve on Java, and the visibility modifiers were no exception. As with Java, there are four modifiers, but with subtle differences aiding API developers:
private— top-level definitions visible in their file, class members only visible in their class.
protected— not applicable to top-level definitions, class members visible in their class and subclasses.
internal— top-level definitions visible in the same module, class members visible in the same module where their class is visible.
public— top-level definitions visible everywhere, class members visible everywhere their class is visible.
Kotlin’s modules, in the context of the
internal visibility modifier, is a set of Kotlin files compiled together, see their documentation for more details.
With top-level definitions, you only have a choice of
public and as with Java the more limited the scope, the better. Where Java’s
protected visibility modifier meant your class became part of your public API, Kotlin’s
internal blocks access from the outside world while allowing your internal use — crucially this also gives access during testing.
Another topic Joshua touches on is to avoid public fields except for constants. Kotlin helps by automatically creating getters and setters for properties meaning should you wish to change the internal data structure you can by overriding the implementations. You of course still have to be careful when these properties are mutable especially with arrays as these are always mutable.