Visibility Modifiers in Kotlin
Visibility modifiers in Kotlin determine the accessibility of classes, objects, interfaces, constructors, functions, and properties.
They control which parts of code can access a particular declaration, helping enforce encapsulation and clean architecture.
1. Why Visibility Modifiers Matter
- Data Safety: Prevent unintended access or modification of variables and methods.
- Code Organization: Clearly define which parts of your code are public APIs and which are internal implementation details.
- Encapsulation: Keep the internal state hidden, exposing only what’s necessary.
- Maintainability: Restricting access reduces the chance of breaking code in other modules or classes.
2. Types of Visibility Modifiers
- public – Default visibility. Accessible from anywhere.
- private – Accessible only within the same class (or file for top-level declarations).
- protected – Accessible within the class and its subclasses.
- internal – Accessible within the same module.
3. How Visibility Modifiers Work
Let’s see examples of each modifier in a Kotlin class:
class Airplane(private val name: String, internal var maxAltitude: Int) {
private fun checkSystems() {
println("Checking all systems for $name")
}
protected fun takeOff() {
println("$name is taking off")
}
internal fun refuel() {
println("$name is refueling")
}
fun status() {
println("Airplane $name, max altitude $maxAltitude")
checkSystems() // private function accessible inside class
}
}
class Jet : Airplane("JetOne", 40000) {
fun jetTakeOff() {
takeOff() // protected function accessible in subclass
// checkSystems() -> Not accessible, private in parent class
refuel() // internal function accessible in same module
}
}
fun main() {
val plane = Airplane("Boeing", 35000)
plane.status() // Accessible
// plane.checkSystems() -> Not accessible, private
// plane.takeOff() -> Not accessible, protected
plane.refuel() // Accessible if in same module
}
3.1 Notes on Each Modifier
- public: No restrictions, can be used anywhere.
- private: Safeguards internal details; can be applied to class members or top-level declarations (file-level).
- protected: Only makes sense in classes; not allowed for top-level declarations.
- internal: Useful for library code or multi-module projects; keeps APIs usable within the same module but hidden outside.
4. Practical Use Cases
- Mark sensitive data like passwords or API keys as
private.
- Expose methods for controlled access as
public or internal.
- Use
protected for methods meant to be extended by subclasses.
- Use
internal for library helpers that shouldn't be exposed outside the module.
5. Technical Interview Questions
- What are the visibility modifiers in Kotlin?
public, private, protected, internal.
- What is the default visibility of a class or function in Kotlin?
public.
- Can top-level functions be protected?
No, protected is only for classes and their members.
- What is the difference between private and internal?
private restricts access to the class or file, internal restricts access to the module.
- Why use internal modifier?
To allow access within the same module but hide it from other modules, useful for libraries or multi-module projects.
6. Key Takeaways
- Visibility modifiers enforce encapsulation and prevent unintended access.
- Choose modifiers based on whether the member should be public, restricted to class, subclass, or module.
- Proper use of visibility modifiers improves maintainability, readability, and safety of code.
- Kotlin’s
internal modifier is unique compared to Java and helps in multi-module project design.