kotlin 可见性有4中:公有、内部、保护和私有。
可见性 | 修饰符 | 类成员声明 | 顶层声明 | 说明 |
---|---|---|---|---|
公有 | public | 所有地方可见 | 所有地方可见 | public是默认修饰符 |
内部 | internal | 模块中可见 | 模块中可见 | 不同于java中的包 |
保护 | protected | 子类中可见 | 顶层声明中不能使用 | |
私有 | private | 类中可见 | 文件中可见 |
注意:kotlin 中没有 Java 的包私有可见性,而具有模块可见性 (internal)。
一、可见性范围
可见性范围主要有三个:模块、源文件 和 类。其中 源文件 和 类 很好理解,下面着重说下模块理解。
模块:
- 一个 IntelliJ IDEA 模块 (module);
- 一个 Eclipse 项目;
- 一个 Maven 项目;
- 一个 Gradle 源代码集合;
- 一个 Ant 编译任务管理的源代码集合。
下面以一个 Android Studio 中的 模块 为例。
二、公有可见性
公有可见性使用 public
关键字,可以修饰顶层函数和属性以及类成员函数及属性,所有被 public
修饰的函数和属性在任何地方都可见。
- 代码块1️⃣
// 模块 kotlin_module
// 文件名: Person.kt
// 代码块 1️⃣
package cn.ak.kotmodule
import java.util.*
/**
* @author lawrence
* @date 2019-05-29 16:45
*/
class Person(val name: String,
private val birthDate: Date,
internal val age: Int) {
internal fun display() {
println("[name: $name, birthDate: $birthDate, age: $age]")
}
}
- 代码块2️⃣
// 模块 app
// 文件名: Main.kt
// 代码块2️⃣
package cn.ak.kot
import cn.ak.kotmodule.Person
import java.util.*
/**
* @author lawrence
*/
fun main(args: Array<String>) {
val now = Date()
val person = Person("小三", now, 18)
println(person.name) // 小三
// println(person.birthDate) // 不能访问 birthDate 属性
// println(person.age) // 不能访问 birthDate 属性
// person.display() // 不能访问 display() 函数
}
三、内部可见性
内部可见性使用
internal
关键字,在同一个模块内部与public
可见性一样。
当代码块2️⃣和代码块1️⃣在 同一模块 (module) 中 internal
修饰的属性、函数就可以正常访问。如代码块2️⃣中println(person.age)
和person.display()
两句代码。
四、保护可见性
保护可见性使用
protected
关键字,protected
可以保证某个父类的子类都能继承该父类的protected
属性和函数。无论父类和子类是否在同一个模块中,父类的protected
属性和函数都可以被子类继承。
open class ProtectedClass(protected val x: Int) {
protected var y: Int = 0
init {
y = x * 2
}
protected fun size(): String = "[$x, $y]"
}
class SubClass(x: Int): ProtectedClass(x) {
fun display() {
println("x=$x") // x 属性从父类继承过来的
println("y=$y") // y 属性从父类继承过来的
println(size()) // size() 函数从父类继承过来的
}
}
注意: kotlin中所有的类默认是 final
不可被继承,所以使用 open
关键字开放 ProtectedClass
继承权限。
五、私有可见性
私有可见性使用
private
关键字,当private
修饰类中的成员属性和函数时,这些属性和函数只能在类的内部可见。当private
修饰顶层属性和函数时,这些属性和函数只在当前文件中可见。
- 类内部可见性
class PrivateClass(private val x: Int = 5, // 类内部可访问
var z: Int) {
private var y = 10 // 类内部可访问
private fun sum() = x + y + z // 类内部可访问
fun showSum() = sum()
fun showSumX2(): Int {
val sum = sum()
return sum * 2
}
}
- 文件内可见性
// PrivateFile.kt
private const val PI = 3.1415
private fun areaCircle(r: Int) = PI * Math.sqrt(r.toDouble()) / 2
fun main(args: Array<String>) {
val r4 = areaCircle(4)
val sqrtPI = Math.sqrt(PI)
println("[r4: $r4, sqrtPI: $sqrtPI]")
}