Kotlin Access Modifiers

Encapsulation is a huge part of OOP. Hiding method and behavior is an important part in achieving encapsulation so Kotlin provides us with access modifiers to help in this effort.

Kotlin has four kinds of access modifiers

  • private—Items marked as private are visible only to the class
  • protected-Items marked as protected are visible to the class and it’s child classes
  • internal—Items marked as internal are accessible to all members of the Kotlin module but are not available outside of the module
  • public—Items marked as public are available to the module and outside of the module using the import statement
    1. Let’s walk through some examples.

      Public

      Public is the default visiblity in Kotlin. If the public keyword is omitted, the member will be marked as public.

      fun printBurgerOfTheDay(burgerName : String = "Never been Feta")
              = println(burgerName)
      

      The printBurgerOfTheDay function is accessible to all code within the module that contains it, plus any module that imports the printBurgerOfTheDay function.

      Internal

      Members marked as internal are visible to the module but are not accessible outside of the module. In other words, internal members act like public members, but they can’t be imported into other modules.

      internal var burgerName = "Mission A-Corn-Plished Burger"
      

      The above variable can be accessed in the module. It may not be imported into another module.

      Protected

      While public and internal access can be used on both class and non-class members, protected only applies to classes.

      open class Cook {
          protected val position = "Cook"
          private val name = "No Name"
      
          override fun toString(): String {
              return position + ", " + name
          }
      }
      
      class Bob : Cook() {
      
          fun printPosition() = println(position)
      }
      

      In the above example, we have a Cook and a Bob class. The Cook class has a protected property called position. The position property is accessible to Cook but it’s also accessible to Bob because Bob is a child class of Cook. In the above example, Bob has a printPosition() function that uses the position property.

      Private

      Private access is the most restrictive. When a member is marked as private, it is only accessible to the class. In the above code snippet, Cook also has a name property, but the name property is not accessible to Bob because it is private.

      Putting it all together

      Below is an example program that shows all of the possible access modifiers in question.

      package ch1.accessmodifiers
      
      /**
       * When no access modifier is used, public is used by default.
       * This printBurgerOfTheDay function is visible to the entire program
       */
      fun printBurgerOfTheDay(burgerName : String = "Never been Feta")
              = println(burgerName)
      
      /**
       * This extension function is marked private. It can't even be used in this module
       */
      private fun String.makeBurgerOfTheDay(burgerName : String) : String = burgerName
      
      /**
       * This variable is marked as internal. It's visible throughout the module,
       * but it can't be accessed outside of the module
       */
      internal var burgerName = "Mission A-Corn-Plished Burger"
      
      /**
       * The position property on Cook is marked as protected. It is only accessible
       * to the Cook class an it's child classes. The name property is private and may
       * only be used by Cook.
       */
      open class Cook {
          protected val position = "Cook"
          private val name = "No Name"
      
          override fun toString(): String {
              return position + ", " + name
          }
      }
      
      class Bob : Cook() {
      
          fun printPosition() = println(position)
      }
      
      fun main(args : Array<String>){
          //Using the public function printBurgerOfTheDay
          printBurgerOfTheDay()
      
          //Printing the internal burgerName variable
          printBurgerOfTheDay(burgerName)
      
          //Create an instance of Cook
          val cook = Cook()
          println(cook)
      
          //Create an instance of Bob
          val bob = Bob()
          bob.printPosition()
      
          //try and use the String extension function
          //DOESN'T COMPILE because makeBurgerOfTheDay is private
          //burgerName = String.makeBurgerOfTheDay("Rest in Peas Burger")
      }
      

      Here is the output when run

      Never been Feta
      Mission A-Corn-Plished Burger
      Cook, No Name
      Cook
      

      References

      https://kotlinlang.org/docs/reference/visibility-modifiers.html

      Advertisement

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

%d bloggers like this: