Kotlin Tutoial

Basics

Control Flow

Array & String

Functions

Collections

OOPs Concept

Exception Handling

Null Safety

Regex & Ranges

Java Interoperability

Miscellaneous

Android

Kotlin Visibility Modifiers

In Kotlin, visibility modifiers determine what other classes have access to a class, method, property, or other member. They are essential for encapsulation in object-oriented programming, allowing for the control of how internal details of a class are exposed (or hidden) from other classes.

Kotlin offers several visibility modifiers:

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

Let's delve into each of these:

1. private

  • When used in a top-level declaration, such as a function, property, or class outside of another class, it means that the member is only visible within that specific file.

  • When used inside a class, it means that the member is only visible within that class.

private val privateValue = "I'm private"

private class PrivateClass {
    private val secret = "No one else can see me!"
}

2. protected

  • This modifier can't be used for top-level declarations.

  • Inside a class, a protected member is visible in its class and its subclasses.

open class Parent {
    protected val protectedValue = "I'm protected"
}

class Child : Parent() {
    fun showValue() {
        println(protectedValue)  // Accessible because it's a subclass of Parent
    }
}

3. internal

  • An internal member is visible to all parts of the same module. A module can be a Gradle module, an IntelliJ IDEA module, etc.

  • This is especially useful in multi-module projects when you want to expose members within the same module but hide them from others.

internal val internalValue = "I'm visible within the same module"

4. public

  • This is the default visibility if you don't specify any modifier.

  • A public member is visible everywhere its containing class or file is visible.

public val publicValue = "I'm visible everywhere"  // 'public' keyword is optional here

Other Points to Remember:

  • In Kotlin, you don't have the package-private level of visibility like in Java (where omitting a visibility modifier allows visibility within the same package). Instead, the closest is internal, but it's broader since it includes the entire module.

  • Kotlin visibility modifiers, especially internal, are designed to provide better encapsulation capabilities, especially in large projects.

Conclusion:

Kotlin's visibility modifiers allow developers to control the exposure of classes, objects, and members. By understanding and effectively using these modifiers, developers can write safer, more encapsulated, and maintainable code. Always choose the most restrictive visibility that suits your needs, ensuring that the implementation details are well-encapsulated and that you're only exposing what's necessary.

1. Public, private, and protected in Kotlin:

In Kotlin, visibility modifiers control the accessibility of classes, interfaces, properties, and methods.

package com.example

class MyClass {
    publicVar // Accessible everywhere
    privateVar // Accessible only within this class
    protectedVar // Accessible within this class and its subclasses
}

2. Default visibility in Kotlin:

If no visibility modifier is specified, the default visibility is public for classes, interfaces, properties, and methods.

package com.example

class MyClass {
    // This is public by default
}

3. Visibility modifiers for classes and interfaces in Kotlin:

Classes and interfaces can have public, private, protected, or internal visibility.

// Default is public
class PublicClass

private class PrivateClass

protected class ProtectedClass

internal class InternalClass

4. Visibility modifiers for properties and methods in Kotlin:

Properties and methods can also have different visibility modifiers.

class MyClass {
    publicFun() // Accessible everywhere
    privateFun() // Accessible only within this class
    protectedFun() // Accessible within this class and its subclasses
}

5. Internal visibility modifier in Kotlin:

The internal modifier makes a declaration visible within the same module.

// Module 1
internal class InternalClass

// Module 2
fun main() {
    val obj = InternalClass() // Accessible within the same module
}

6. Visibility modifiers and module boundaries in Kotlin:

internal visibility ensures that a declaration is visible within the same module but not outside.

// Module 1
internal class InternalClass

// Module 2 (Compile-time error)
fun main() {
    val obj = InternalClass() // Not accessible outside the module
}

7. Companion objects and visibility in Kotlin:

Companion objects share the visibility of their containing class.

class MyClass {
    companion object {
        private fun privateFun() {}
        internal fun internalFun() {}
    }
}

8. Visibility modifiers in nested classes and inner classes in Kotlin:

Nested classes have access to their outer class, and inner classes can access private members of the outer class.

class Outer {
    private val outerVar = 42

    class Nested {
        // Cannot access outerVar
    }

    inner class Inner {
        fun accessOuterVar() = outerVar
    }
}

9. Visibility modifiers and extension functions in Kotlin:

Extension functions have the same visibility as regular functions.

class MyClass {
    private fun privateFun() {}

    fun useExtension() {
        privateFun() // Accessible from extension function
    }
}

// Extension function has access to privateFun
fun MyClass.extensionFunction() {
    privateFun()
}

10. Visibility modifiers and data classes in Kotlin:

Data classes generate component functions with the same visibility as the properties.

data class Person(private val name: String, val age: Int)

fun main() {
    val person = Person("Alice", 25)
    val (name, age) = person // Accessible within the same module
}

11. Visibility modifiers and top-level declarations in Kotlin:

Top-level declarations are visible to everything in the same file by default.

// Visible within the same file
private val topLevelVar = 42

fun topLevelFunction() {}

12. Overriding and visibility in Kotlin:

Overriding members must have equal or higher visibility than the overridden members.

open class Parent {
    protected open fun protectedFun() {}
}

class Child : Parent() {
    // Visibility must be protected or public
    override fun protectedFun() {}
}