Visibility Modifiers (Phạm vi truy cập)
🎯 Mục tiêu: Kiểm soát quyền truy cập vào code của bạn bằng các từ khóa:
public,private,protected,internal.
💡 Các mức độ truy cập
Kotlin có 4 visibility modifiers:
- public (mặc định): Truy cập từ bất cứ đâu.
- private: Chỉ truy cập trong phạm vi khai báo (file hoặc class).
- protected: Truy cập trong class và subclasses (không có cho top-level).
- internal: Truy cập trong cùng Module.
📦 Top-level Declarations
Đối với biến, hàm, class khai báo trực tiếp trong file:
// file: Example.kt
package foo
fun baz() {} // public: dùng ở đâu cũng được
private fun foo() {} // private: chỉ dùng được trong file Example.kt
internal val bar = 5 // internal: chỉ dùng được trong module này🏛️ Class Members
Đối với member trong Class:
open class Outer {
private val a = 1 // Chỉ trong Outer
protected open val b = 2 // Trong Outer + Subclasses
internal val c = 3 // Trong cùng Module
val d = 4 // Public (mặc định)
protected class Nested {
public val e: Int = 5
}
}
class Subclass : Outer() {
// a không thấy
// b, c, d thấy được
// Nested thấy được
override val b = 5 // Vẫn giữ protected
}
class Unrelated(o: Outer) {
// o.a, o.b không thấy
// o.c, o.d thấy được (nếu cùng module)
}Khác với Java, protected trong Kotlin không visibility trong cùng package, chỉ subclasses thôi.
🏗️ Constructors
Để thay đổi visibility của constructor, bạn phải thêm từ khóa constructor:
class C private constructor(a: Int) { ... }Class này không thể được khởi tạo từ bên ngoài!
📦 Modules là gì?
Modifier internal giới hạn trong Module. Một module trong Kotlin có thể là:
- Một IntelliJ IDEA module.
- Một Maven project.
- Một Gradle source set (VD:
main,test).
Điều này cực kỳ hữu ích để tạo các thư viện: bạn có thể có các hàm tiện ích public cho nội bộ thư viện dùng (internal), nhưng người dùng thư viện không thấy được, giữ API sạch sẽ.
🛠️ Thực hành
Bài tập 1: Thiết kế API
Tạo một class Library chỉ cho phép truy cập qua các hàm public, giấu kín implementation details.
class Library internal constructor() { // Chỉ tạo được trong module
private val books = mutableListOf<String>()
fun addBook(title: String) {
books.add(title)
log("Added $title")
}
private fun log(msg: String) {
println("[Lib]: $msg")
}
}
// ❌ Không thể tạo Library() ở module khác✅ Checklist
- Hiểu
publiclà mặc định - Dùng
privateđể đóng gói dữ liệu - Dùng
internalcho các thành phần nội bộ module - Phân biệt
protectedcủa Kotlin và Java