Kotlin Visibility Modifiers

Kotlin Visibility Modifiers control the visibility or accessibility of classes, properties, functions, and other elements within a Kotlin program. These modifiers help in encapsulating code, enforcing access restrictions, and promoting good software design practices. In Kotlin, there are four visibility modifiers: public, private, protected, and internal. Let’s explore each modifier with a real-world example and output.

public Modifier

The public modifier is the default visibility modifier in Kotlin. It means that the element is accessible from any other part of the codebase, including external modules.

class Car {
    val model: String = "Toyota Camry"
    fun startEngine() {
        println("Starting the engine of $model")
    }
}

In this example, the Car class and its properties (model) and functions (startEngine) are all public by default. They can be accessed from anywhere within the program.

private Modifier

The private modifier restricts the visibility of an element to the current file or scope. It ensures that the element is not accessible from outside the containing class or function.

class Employee {
    private val employeeId: Int = 1001
    private fun calculateSalary() {
        // Calculation logic
    }
}

In this example, the employeeId property and calculateSalary function are private within the Employee class. They cannot be accessed from outside the class, providing encapsulation and data hiding.

protected Modifier

The protected modifier allows visibility to the containing class and its subclasses. It’s often used in inheritance scenarios to restrict access to certain elements while allowing subclasses to access them.

open class Vehicle {
    protected val brand: String = "Toyota"
    protected fun drive() {
        println("Driving the $brand")
    }
}

class Car : Vehicle() {
    fun startDriving() {
        drive()  // Accessing protected function from subclass
    }
}

In this example, the brand property and drive function in the Vehicle class are protected, making them accessible to subclasses like Car.

internal Modifier

The internal modifier restricts visibility to the same module. A module in Kotlin is a set of Kotlin files compiled together, typically representing a single unit of functionality or a library.

internal class UtilityFunctions {
    internal fun performTask() {
        println("Performing internal task")
    }
}

In this example, the UtilityFunctions class and its performTask function are internal, meaning they can be accessed within the same module but not from external modules.

Example: Library Module

Let’s consider a real-world scenario of a Kotlin library module with visibility modifiers.

Library Module (library.kt):

package com.example.library

public class LibraryClass {
    private val privateProperty: String = "Private"
    internal val internalProperty: String = "Internal"
    protected val protectedProperty: String = "Protected"
    public val publicProperty: String = "Public"
}

Main Application (main.kt):

import com.example.library.LibraryClass

fun main() {
    val libraryObject = LibraryClass()
    
    // Accessing properties from the library module
    println(libraryObject.publicProperty)  // Output: Public
    println(libraryObject.internalProperty)  // Accessible due to same module
    // println(libraryObject.privateProperty)  // Error: privateProperty is private
    
    // Accessing protected property (not allowed from outside subclasses)
    // println(libraryObject.protectedProperty)  // Error: protectedProperty has protected visibility
}
  • The publicProperty is accessible from the main application as it has public visibility.
  • The internalProperty is also accessible because both files (library.kt and main.kt) are part of the same module.
  • Attempting to access privateProperty or protectedProperty from outside their respective scopes results in compilation errors due to their restricted visibility.
Visibility modifiers in Kotlin play a crucial role in maintaining encapsulation, controlling access, and promoting modular development practices. By understanding and using visibility modifiers effectively, Kotlin developers can create well-structured and maintainable codebases, enhancing code readability and scalability.