In Kotlin, visibility modifiers determine the accessibility of classes, objects, interfaces, constructors, functions, properties, and their setters. Understanding visibility modifiers is crucial for designing robust and maintainable code. Kotlin provides four visibility modifiers:

  1. public
  2. private
  3. protected
  4. internal

  1. Public

The public modifier is the default visibility. It means that the declaration is visible everywhere.

// File: PublicExample.kt
class PublicExample {
    public val publicProperty: String = "I am public"
    
    public fun publicFunction() {
        println("This is a public function")
    }
}

fun main() {
    val example = PublicExample()
    println(example.publicProperty) // Accessible
    example.publicFunction() // Accessible
}

  1. Private

The private modifier restricts the visibility to the containing declaration. If you declare a member as private, it will only be accessible within the class or file it is declared in.

// File: PrivateExample.kt
class PrivateExample {
    private val privateProperty: String = "I am private"
    
    private fun privateFunction() {
        println("This is a private function")
    }
    
    fun accessPrivateMembers() {
        println(privateProperty) // Accessible within the class
        privateFunction() // Accessible within the class
    }
}

fun main() {
    val example = PrivateExample()
    // println(example.privateProperty) // Not accessible
    // example.privateFunction() // Not accessible
    example.accessPrivateMembers() // Accessible
}

  1. Protected

The protected modifier is similar to private but with one additional feature: it is also accessible in subclasses.

// File: ProtectedExample.kt
open class ProtectedExample {
    protected val protectedProperty: String = "I am protected"
    
    protected fun protectedFunction() {
        println("This is a protected function")
    }
}

class SubclassExample : ProtectedExample() {
    fun accessProtectedMembers() {
        println(protectedProperty) // Accessible in subclass
        protectedFunction() // Accessible in subclass
    }
}

fun main() {
    val example = SubclassExample()
    example.accessProtectedMembers() // Accessible
    // println(example.protectedProperty) // Not accessible
    // example.protectedFunction() // Not accessible
}

  1. Internal

The internal modifier makes the declaration visible within the same module. A module in Kotlin is a set of Kotlin files compiled together.

// File: InternalExample.kt
internal class InternalExample {
    internal val internalProperty: String = "I am internal"
    
    internal fun internalFunction() {
        println("This is an internal function")
    }
}

fun main() {
    val example = InternalExample()
    println(example.internalProperty) // Accessible within the same module
    example.internalFunction() // Accessible within the same module
}

Practical Exercise

Exercise 1: Visibility Modifiers

  1. Create a class Person with the following properties and methods:

    • name (public)
    • age (private)
    • address (protected)
    • displayInfo (internal) - This method should print the name and address.
  2. Create a subclass Employee that inherits from Person and has an additional property employeeId (public).

  3. In the main function, create an instance of Employee and try to access all properties and methods.

Solution

// File: Person.kt
open class Person(val name: String, private val age: Int, protected val address: String) {
    internal fun displayInfo() {
        println("Name: $name, Address: $address")
    }
}

// File: Employee.kt
class Employee(name: String, age: Int, address: String, val employeeId: String) : Person(name, age, address) {
    fun showEmployeeDetails() {
        println("Employee ID: $employeeId")
        displayInfo() // Accessible
    }
}

// File: Main.kt
fun main() {
    val employee = Employee("John Doe", 30, "123 Main St", "E12345")
    println(employee.name) // Accessible
    // println(employee.age) // Not accessible
    // println(employee.address) // Not accessible
    employee.showEmployeeDetails() // Accessible
    // employee.displayInfo() // Not accessible
}

Summary

In this section, we covered the four visibility modifiers in Kotlin: public, private, protected, and internal. We explored how each modifier affects the accessibility of classes, properties, and methods. Understanding these modifiers is essential for encapsulating and protecting your code effectively. In the next section, we will delve into data classes and sealed classes, which provide additional ways to structure and manage your data in Kotlin.

© Copyright 2024. All rights reserved