🔐 Kotlin – Visibility Modifiers: Control Access with public
, private
, internal
, and protected
🧲 Introduction – Why Learn Kotlin Visibility Modifiers?
Visibility modifiers in Kotlin help you control access to classes, properties, functions, and constructors. They improve code security, readability, and maintainability by encapsulating internal details and exposing only what’s necessary. Kotlin uses four main visibility modifiers: public
, private
, protected
, and internal
.
🎯 In this guide, you’ll learn:
- The purpose and use of each visibility modifier
- How visibility affects top-level vs member declarations
- Visibility rules across packages and modules
- Real-world best practices for Kotlin encapsulation
🔓 Kotlin Visibility Modifiers Overview
Modifier | Class Members (Inside Class) | Top-Level Declarations (Global) |
---|---|---|
public | Accessible everywhere (default) | Accessible from any file or module |
private | Accessible only inside the declaring class | Accessible only inside the declaring file |
protected | Accessible in the declaring class and subclasses | ❌ Not applicable to top-level |
internal | Accessible within the same module | Accessible in the same module |
✅ 1. public
– Open Access (Default Modifier)
class Engine {
fun start() = println("Engine started")
}
✔️ This function is public
by default and can be accessed from any file or class.
🔒 2. private
– Restrict to File or Class
🔹 For class members:
class Account {
private var balance: Int = 0
fun deposit(amount: Int) {
balance += amount
}
}
✔️ balance
is only accessible within the Account
class.
🔹 For top-level declarations:
private fun log(message: String) {
println("LOG: $message")
}
✔️ log()
can only be accessed within the same Kotlin file.
🧬 3. protected
– Inheritance-Only Access
open class Base {
protected fun sayHello() = println("Hello from Base")
}
class Derived : Base() {
fun callParent() {
sayHello() // Accessible here
}
}
✔️ sayHello()
is only accessible in Base and its subclasses, not outside.
❌ protected
cannot be used for top-level functions or properties.
🧩 4. internal
– Visible Within the Same Module
internal class Repository {
fun fetch() = println("Fetching data...")
}
✔️ Repository
is accessible only within the same module, not from other libraries.
🔎 Visibility Scope Summary Table
Modifier | Class Members | Subclasses | Same File | Other Files (Same Module) | Other Modules |
---|---|---|---|---|---|
public | ✅ Yes | ✅ Yes | ✅ Yes | ✅ Yes | ✅ Yes |
private | 🔒 Only within class/file | ❌ No | ✅ Yes (if file-level) | ❌ No | ❌ No |
protected | ✅ Yes | ✅ Yes | ❌ No | ❌ No | ❌ No |
internal | ✅ Yes | ✅ Yes | ✅ Yes | ✅ Yes | ❌ No |
⚠️ Common Pitfalls & Mistakes
❌ Mistake | ✅ Fix |
---|---|
Using protected for top-level functions | Not allowed—use internal or private instead |
Exposing sensitive data with public | Use private or internal for encapsulation |
Expecting internal to restrict fully | It’s only limited within the module, not per file |
Accessing private property outside class | Declare accessor functions or change to internal |
✅ Best Practices for Kotlin Visibility
Practice | Benefit |
---|---|
Use private by default | Protects class internals from misuse |
Use internal for shared code in modules | Keeps API clean when sharing logic across files |
Expose minimal surface via public | Reduces complexity and improves maintainability |
Use protected for inheritance customization | Allows subclass-specific behavior |
📌 Summary – Recap & Next Steps
Visibility modifiers in Kotlin are essential for controlling code accessibility. By choosing the right modifier, you can enforce encapsulation, enhance security, and prevent misuse of internal APIs.
🔍 Key Takeaways:
public
: default; accessible everywhereprivate
: restricts to class or fileprotected
: only for class and subclassesinternal
: limits access to the same module
⚙️ Practical Use:
Visibility modifiers are widely used in library APIs, data encapsulation, domain logic protection, and module-level code organization.
❓ FAQs – Kotlin Visibility Modifiers
❓ What is the default visibility in Kotlin?
✅ public
is the default visibility modifier in Kotlin, meaning it’s accessible everywhere.
❓ When should I use internal
?
✅ Use internal
when you want the class/function accessible only within the same module (e.g., inside an app or library).
❓ Can I use protected
for top-level functions in Kotlin?
✅ No. protected
is only allowed for class members, not for top-level declarations.
❓ What is the difference between private
and internal
?
✅ private
restricts access to the class or file, while internal
restricts access to the entire module.
❓ Is it a good idea to make everything public
?
✅ No. It exposes your implementation unnecessarily and can lead to tight coupling. Prefer private
or internal
by default.
Share Now :