Kotlin Visibility Modifiers

This post is about Access/Visibility modifiers in kotlin and how to use them.

Access Modifiers

In Kotlin, visibility modifiers are used to restrict the accessibility of Classes, objects, interfaces, constructors, functions, properties and their setters to a certain level. Getters always have the same visibility as the property.

There are four visibility modifiers in Kotlin:

  • public
  • protected
  • internal
  • private

Note: If visibility modifier is not specified, it is public by default.

Visibility Modifiers Inside Package

  • public : declarations will be visible everywhere.
  • Private: visible inside the file containing the declaration.
  • internal: visible inside the same module.
  • Protected: not available for top-level declarations.

Example

// file name: KotlinTestFile.kt

package com.mytest

var age = 25  // public by default and visible everywhere

private var mobileNumber = 123456 // visible inside KotlinTestFile.kt

internal var companyName = "MyCompany"   // visible inside the same module

//error: cannot create protected functions/properties in kotlin file
//protected var id = 12345678

var name = "John"  // public by default and visible everywhere
    get() = field   // visibility same as its property
    private set(value) {   // visible inside KotlinTestFile.kt
        field = value
    }

private class classA {}   // visible inside KotlinTestFile.kt

Visibility Modifiers Inside Classes and Interfaces

Visibility modifiers for members (functions, properties) declared inside a class:

  • public : visible to any client who can see the declaring class.
  • Private: visible inside the class only.
  • internal: visible to any client inside the module that can see the declaring class.
  • Protected: visible inside the class and its subclasses.

Note: If you override a protected member in the derived class without specifying its visibility, its visibility will also be protected.

Example

package com.mytest

open class Test01() {

    // private to Test01(Base class)
    private fun privateMethod() {
        println("private method call")
    }

    // public by default and visible everywhere
    fun publicMethod() {
        privateMethod()
        println("public method call")
    }

    // visible to Test01(Base class) and Test02(Derived class)
    protected fun protectedMethod() {
        println("protected method call")
    }

    // visible inside the same module
    internal fun internalMethod() {
        println("internal method call")
    }
}

fun main() {
//creating Test01 instance
    val test01 = Test01()

    //publicMethod() and internalMethod() of Test01 class are visible
    test01.publicMethod()
    test01.internalMethod()

    //compile error: protectedMethod() and privateMethod() of Test01 class are not visible

    //test01.protectedMethod()   //accessible in subclasses only

    //test01.privateMethod()   //accessible only inside the class Test01

}

// Test02 inheriting class Test01
class Test02 : Test01() {
    fun newMethod() {
        // protectedMethod() ,publicMethod() ,internalMethod() of the Test01 class are visible
        // privateMethod() is not visible
        protectedMethod()

        publicMethod()

        internalMethod()

        //privateMethod()  // compile error

    }
}

Changing Visibility of a Constructor

By default, the visibility of a constructor is public. However, you can change it. For that, you need to explicitly add constructor keyword.

The constructor is public by default in the example below:

class Test(val a: Int) {
    // code
}

OR 

//by default the constructor is public
class Test constructor(val a: Int) {
  // code 
}

Here’s how you can change its visibility. Here the constructor is private.

class Test private constructor(val a: Int) {
    // code
}

Note: In Kotlin, local functions, variables and classes cannot have visibility modifiers.

Leave a Reply