Kotlin 可见性控制怎么设置?类成员的访问修饰符有哪些?

文章导读
Previous Quiz Next Kotlin 的可见性修饰符是用于设置 class、object、interface、constructor、function 以及 property 和其 setter 可见性的关键字。虽然 getter 始终与其 property
📋 目录
  1. Public 修饰符
  2. Private 修饰符
  3. Protected 修饰符
  4. Internal 修饰符
  5. 测试时间 (面试 & 考试准备)
A A

Kotlin - 可见性控制(修饰符)



Previous
Quiz
Next

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 或子类中访问。