Kotlin - 可见性控制(修饰符)
Kotlin 的可见性修饰符是用于设置 class、object、interface、constructor、function 以及 property 和其 setter 可见性的关键字。虽然 getter 始终与其 property 具有相同的可见性,因此我们无法单独设置其可见性。
Setter 是用于设置 property 值的 function,而 getter 是用于获取这些 property 值的 function。
Kotlin 中有四种可见性修饰符:
public
private
protected
internal
默认可见性是 public。这些修饰符可以用于多个位置,例如 class header 或 method body。让我们详细了解这些修饰符:
Public 修饰符
Public 修饰符可以在项目工作区中的任何位置访问。如果没有指定访问修饰符,则默认处于 public 作用域。在我们之前的所有示例中,都没有提及任何修饰符,因此它们全部处于 public 作用域。以下是一个示例,用于更详细地理解如何声明 public 变量或 method。
class publicExample {
val i = 1
fun doSomething() {
}
}
在上面的示例中,我们没有提及任何修饰符,因此这里定义的 method 和变量默认是 public 的。虽然上面的示例也可以显式使用 public 修饰符来编写,如下所示:
public class publicExample {
public val i = 1
public fun doSomething() {
}
}
Private 修饰符
Class、method、package 和其他 property 都可以使用 private 修饰符声明。该修饰符几乎与 public 意思完全相反,即 private 成员无法在其作用域外部访问。一旦某物被声明为 private,则它只能在其直接作用域内访问。例如,一个 private package 只能在特定文件中访问。一个 private class 或 interface 只能由其数据成员访问,等等。
private class privateExample {
private val i = 1
private fun doSomething() {
}
}
在上面的示例中,class privateExample 只能在同一源文件中访问,而变量 i 和 method doSomething 只能在 class privateExample 内部访问。
示例
让我们看一个简单的示例,展示 private 成员的使用:
open class A() {
private val i = 1
fun doSomething(){
println("Inside doSomething" )
println("Value of i is $i" )
}
}
class B : A() {
fun printValue(){
doSomething()
// println("Value of i is $i" )
}
}
fun main(args: Array<String>) {
val a = A()
val b = B()
b.printValue()
}
运行上述 Kotlin 程序时,将生成以下输出:
Inside doSomething Value of i is 1
在这里,我们无法在 class B 中访问变量 i,因为它被定义为 private,这意味着它只能在 class 内部访问,而在其他地方无法访问。
Protected 修饰符
Protected 是 Kotlin 的另一个访问修饰符,目前不能用于顶级声明,例如任何 package 都不能是 protected 的。Protected 的 class 或 interface 或属性或 function 仅对 class 本身及其子类可见。
package one;
class A() {
protected val i = 1
}
class B : A() {
fun getValue() : Int {
return i
}
}
在上面的例子中,变量 i 被声明为 protected,因此,它仅对 class 本身及其子类可见。
示例
让我们看一个简单的示例,展示 protected 成员的使用:
open class A() {
protected val i = 1
protected fun doSomething(){
println("Inside doSomething" )
println("Value of i is $i" )
}
}
class B : A() {
fun printValue(){
doSomething()
println("Value of i is $i" )
}
}
fun main(args: Array<String>) {
val a = A()
val b = B()
//a.doSomething()
b.printValue()
}
当你运行上面的 Kotlin 程序时,它将生成以下输出:
Inside doSomething Value of i is 1 Value of i is 1
在这里,我们甚至不能使用 class A 的对象来调用 doSomething(),因为它被定义为 protected,这意味着它只能在 class 本身或其子类中访问。
Internal 修饰符
Internal 是 Kotlin 中新添加的修饰符。如果任何东西被标记为 internal,那么该特定字段将被标记为 internal 字段。Internal package 仅在其实现所在的 module 内可见。Internal class interface 仅由同一 package 或 module 中的其他 class 可见。在下面的示例中,我们将看到如何实现一个 internal 方法。
package one
internal class InternalExample {
}
class publicExample{
internal val i = 1
internal fun doSomething() {
}
}
在上面的示例中,class InternalExample 仅能从同一 module 内访问,同样,变量 i 和 function doSomething() 也仅能从同一 module 内访问,尽管 class publicExample 可以从任何地方访问,因为这个 class 默认具有 public 可见性。
示例
让我们看一个简单的示例,展示 internal 成员的使用:
package com..modifiers
open class A() {
internal val i = 1
internal fun doSomething(){
println("Inside doSomething" )
println("Value of i is $i" )
}
}
class B : A() {
fun printValue(){
doSomething()
println("Value of i is $i" )
}
}
fun main(args: Array<String>) {
val a = A()
val b = B()
a.doSomething()
b.printValue()
}
当你运行上面的 Kotlin 程序时,它将生成以下输出:
Inside doSomething Value of i is 1 Inside doSomething Value of i is 1 Value of i is 1
测试时间 (面试 & 考试准备)
Q 1 - 以下哪个不是 Kotlin 中的可见性修饰符:
A - public
B - private
C - abstract
D - internal
答案:C
解释
Abstract 不是 Kotlin 中的可见性修饰符,尽管它用于定义 abstract class。
Q 2 - 关于 protected 可见性修饰符,以下哪个是正确的?
A - Protected 成员不能在 class 外部访问
B - Protected 成员可以被子类访问
C - Kotlin 不允许将 class 定义为 protected
D - Protected 成员仅能在其 class 或子类中访问。
答案:D
解释
是的,protected 成员仅能在其 class 或子类中访问。