Kotlin Access Modifiers
$count++; if($count == 1) { include "../mobilemenu.php"; } if ($count == 2) { include "../sharemediasubfolder.php"; } ?>
Access modifiers control visibility of classes, objects, interfaces, constructors, functions, properties, and their setters. Kotlin provides public, internal, protected, and private.
1. public (Default)
Visible everywhere. If you omit a modifier, public
is assumed.
// default is public
class PublicClass {
public val x = 1
fun foo() = x
}
val pc = PublicClass()
println(pc.x)
println(pc.foo())
2. internal
Visible within the same module (e.g., a Gradle project). Hides declarations from other modules.
// in module A
internal class InternalClass {
internal fun bar() = "Hello"
}
// in module B (cannot see InternalClass)
// val ic = InternalClass() // Error: unresolved reference
3. private (Top-Level)
At top-level (in a file), private
restricts visibility to that file only.
// File: Utils.kt
private fun helper() = 42
fun publicApi() = helper()
Usage: helper()
is inacces
sible outside Utils.kt
;
4. private (Member)
Inside a class, private
restricts to that class only (not even subclasses).
class Secret {
private val code = "1234"
fun reveal() = code
}
val s = Secret()
// println(s.code) // Error: cannot access private property
5. protected
Visible in the declaring class and its subclasses. Not available at top-level.
open class Base {
protected val secret = "shh"
}
class Derived: Base() {
fun show() = secret
}
val d = Derived()
println(d.show())
// println(d.secret) // Error: secret is protected
6. private set
You can expose a read-only val
but restrict its setter to private
.
class Counter {
var count: Int = 0
private set
fun inc() { count++ }
}
val c = Counter()
c.inc()
println(c.count) // OK
// c.count = 5 // Error: setter is private
7. Visibility on Constructors
Constructors can have modifiers to control instantiation.
class MyClass private constructor(val x: Int) {
companion object {
fun create(x: Int) = MyClass(x)
}
}
// val m = MyClass(5) // Error: constructor is private
val m2 = MyClass.create(5)
8. local declarations
Declarations inside functions cannot have visibility modifiers—they are always local and invisible outside.
fun foo() {
val localVar = 10 // always invisible outside foo()
}
9. Combining Modifiers
You may combine private
with sealed
or abstract
to restrict subclassing and visibility.
private sealed class Expr {
class Num(val value: Int): Expr()
class Op(val left: Expr, val right: Expr): Expr()
}
fun eval(e: Expr): Int = when(e) {
is Expr.Num -> e.value
is Expr.Op -> eval(e.left) + eval(e.right)
}
10. Summary & Best Practices
- Default to public only for API you intend to expose.
- Use internal to hide module implementation details.
- Favor private to encapsulate implementation and maintain invariants.
- Use protected sparingly—prefer composition over inheritance.
- Restrict setters with private set
to control state mutation.
- Control constructors visibility to enforce valid object creation.
- Avoid top-level protected/private—use file-level private only.
- Document visibility decisions in KDoc for clarity.