Visibility Modifiers
Part of the Object Oriented Programming section of Coddy's Kotlin journey. Lesson 8 of 57.
Encapsulation means a class controls how its data is used. Visibility modifiers decide who can see a member. private hides it from everything outside the class, so the class's own methods are the only way in:
class Account {
private var balance = 0
fun deposit(amount: Int) {
if (amount > 0) balance += amount
}
fun report() = "balance: $balance"
}Inside main:
val a = Account()
a.deposit(50)
a.deposit(-999)
println(a.report())
// a.balance = 1_000_000 // error: cannot access 'balance': it is privateOutput:
balance: 50Kotlin has four modifiers. Without one a declaration is public, visible everywhere:
public // default: visible everywhere
internal // visible in the same module (app or library)
protected // visible in the class and its subclasses
private // visible inside the class (or file, for top-level declarations)Private helper functions keep the public surface small. Callers see what the class does, not how:
class Password(private val text: String) {
val isStrong: Boolean
get() = hasDigit() && text.length >= 8
private fun hasDigit() = text.any { it.isDigit() }
}Inside main:
println(Password("secret123").isStrong)
println(Password("short1").isStrong)Output:
true
falseConstructor properties take modifiers too: private val stores a value that outside code cannot read. Hiding data is what lets a class check every change and keep its rules:
class Locker(private val code: String) {
private val items = mutableListOf<String>()
fun store(item: String, code: String): Boolean {
if (code != this.code) return false
items.add(item)
return true
}
}Challenge
EasyComplete the class Locker(private val code: String). Its items list is private. store(item, code) adds the item only when the code matches and returns whether it did; open(code) returns the items joined with , (or empty) when the code matches, and wrong code otherwise.
The supplied code reads the locker's code and then commands put <code> <item> or open <code>. It prints stored or denied for each put and the result of each open.
Your code goes in Locker.kt. Main.kt holds the supplied input/output code and cannot be edited.
Try it yourself
fun main() {
// Supplied input/output code: keep it as it is
val input = generateSequence(::readLine).toList()
val locker = Locker(input[0])
for (cmd in input.drop(1)) {
val p = cmd.split(" ")
if (p[0] == "put") println(if (locker.store(p[2], p[1])) "stored" else "denied")
else println(locker.open(p[1]))
}
}
This lesson includes a short quiz. Start the lesson to answer it and track your progress.
All lessons in Object Oriented Programming
1Classes and Objects
Working With FilesDefining ClassesPrimary Constructorsinit Blocks and ValidationSecondary ConstructorsRecap - Library Card4Inheritance
Open Classes and SubclassesOverriding Memberssuper and ConstructorsAbstract ClassesRecap - Staff Directory2Properties and Encapsulation
Custom AccessorsVisibility ModifiersPrivate Setterslazy and lateinitRecap - Bank Account5Interfaces
Declaring InterfacesDefault MethodsMultiple InterfacesInterfaces as TypesRecap - Payment Methods8Generics
Generic FunctionsGeneric ClassesType ConstraintsVariance With in and outRecap - Priority Queue11Project: Library Management
Books and MembersBorrowing BooksPractice on your own: Kotlin playground