一、研讨主题引入:为什么要关注 Kotlin 的访问权限?
在面向对象编程中,访问权限是 "封装性" 的核心体现 ------ 它决定了哪些代码能访问类的成员,直接影响代码的安全性、可维护性。Kotlin 的访问权限规则(与 Java 有差异)是初学者的易混淆点,本次以示例代码为载体,拆解不同权限的表现与场景。
二、示例代码的权限类型梳理
基于研讨代码,先明确 Kotlin 中 4 种核心访问权限的定义:
| 权限修饰符 | 可访问范围 | 代码对应成员 |
|---|---|---|
public(默认) |
任意位置 | Person.name |
protected |
本类、子类(但类外部不可访问) | Person.birthday |
private |
本类 + 伴生对象 | Person.password |
private[this] |
仅当前类的当前实例(伴生对象也不可访问) | Person.money |
scala
object Test {
private var p: Person? = Unit
// print(p?.password) 在伴生对象中可以访问
// private[this] 在伴生对象中不可以访问
// print(p?.money)
class Person {
var name: String = "xx" // 公开的
protected var birthday: String = "2000-10-10"
private var password: String = "123456"
private[this] var money: Int = 100
fun (): Unit {
print(money)
}
}
class Son extends Person {
// 1. protected在子类中可以访问
// 2. protected在子类中
// 3. private在子类中不可以访问
}
fun main(args: Array<String>): Unit {
val p1 = new Person()
// 1. print(p1.name)
// 2. protected在类的外部无法访问
// print(p1.birthday)
new Son()
// 3. 在伴生对象中间,可以的私有成员
Person.test(p1)
}
}
三、代码中权限规则的实践验证
1. public(默认)的表现
- 代码中
Person.name未写修饰符,默认是public - 验证:
main函数中print(p1.name)可正常执行(类外部可访问)
2. protected的 "子类可用、外部不可用"
-
代码中
Person.birthday用protected修饰:- 合法场景:
Son类(子类)中可以访问birthday; - 非法场景:
main函数中print(p1.birthday)会报错(类外部无访问权)。
- 合法场景:
3. private与private[this]的关键差异
这是 Kotlin 独有的细节,需重点辨析:
private(普通) :代码中Person.password是private,伴生对象Test中print(p?.password)是合法的(伴生对象与类本身 "同属一个单元");private[this]:代码中Person.money用private[this]修饰,仅能在Person类的自身实例方法 中访问(如Person内的fun()可以print(money)),但伴生对象中print(p?.money)会报错。
4. 伴生对象的 "特殊访问权"
Kotlin 中,object Test是Person的伴生对象 (需注意:代码中写法不规范,正确伴生对象应是class Person { companion object Test { ... } }),其特殊权限是:能访问类的private成员(如password),但不能访问private[this]成员(如money)。
四、研讨总结:访问权限的使用建议
- 优先用
private/private[this]:减少不必要的暴露,提升封装性; protected用于 "子类需要扩展、但外部无需访问" 的成员;- 避免滥用
public:仅对外暴露必要的接口,隐藏内部实现细节。
五、拓展思考
请修改代码,在Son类中尝试访问birthday,并验证private[this]在 "不同实例" 中的访问限制 ------ 要不要我帮你补充一份权限验证的实操代码示例?