ZetCode

Kotlin public 关键字

最后修改于 2025 年 4 月 19 日

Kotlin 的可见性修饰符控制对类、对象和成员的访问。public 关键字是最宽松的可见性修饰符。本教程通过实际示例深入探讨 public 关键字。

基本定义

Kotlin 中的 public 关键字使声明可以从任何地方访问。如果未指定任何可见性修饰符,则它是默认的可见性修饰符。公共成员可以从同一模块或其它模块中的任何其他代码访问。

默认公共可见性

在 Kotlin 中,如果未指定可见性修饰符,则声明默认为公共。这适用于类、函数和属性。在这些情况下,显式使用 public 是可选的。

DefaultPublic.kt
package com.zetcode

class Person { // Implicitly public
    fun greet() = println("Hello!") // Implicitly public
}

fun main() {
    val person = Person()
    person.greet() // Output: Hello!
}

此处,Person 类及其 greet() 函数默认为公共。它们可以从同一模块或依赖于此模块的其他模块中的任何地方访问。

显式公共修饰符

虽然 public 是默认设置,但您可以显式使用 public 修饰符以使代码更清晰。这使得可见性意图对阅读代码的其他开发人员来说一目了然。

ExplicitPublic.kt
package com.zetcode

public class Calculator {
    public fun add(a: Int, b: Int): Int = a + b
}

fun main() {
    val calc = Calculator()
    println(calc.add(5, 3)) // Output: 8
}

此示例显示在类及其方法上显式使用 public 修饰符。其行为与默认情况相同,但可见性已明确声明。

公共顶级函数

顶级函数(不在类中的函数)默认为公共。它们可以从模块中的任何位置以及导入它们的其他模块访问。

TopLevelFunction.kt
package com.zetcode

// Implicitly public
fun sayHello(name: String) = println("Hello, $name!")

fun main() {
    sayHello("Alice") // Output: Hello, Alice!
}

sayHello 函数默认为公共,可以从任何地方调用。如果此文件是库的一部分,则其他项目可以导入并使用此函数。

公共属性

Kotlin 中的属性可以声明为公共,这意味着它们的 getter(如果为 var,则还有 setter)可以从任何地方访问。这是属性的默认可见性。

PublicProperty.kt
package com.zetcode

class Circle {
    public val pi: Double = 3.14159 // Explicit public
    var radius: Double = 0.0 // Implicitly public
    
    fun area(): Double = pi * radius * radius
}

fun main() {
    val circle = Circle()
    circle.radius = 5.0
    println("Area: ${circle.area()}") // Output: Area: 78.53975
    println("PI: ${circle.pi}") // Output: PI: 3.14159
}

pi 和 radius 属性都是公共的(一个显式,一个默认)。可以从类外部修改 radius,因为它是一个 var,而 pi 是一个 val,只读。

在不同的包中为公共

公共声明可以在同一模块内的不同包之间访问。如果正确导入,它们也可以从其他模块访问。

DifferentPackages.kt
// File 1: com/zetcode/utils/Logger.kt
package com.zetcode.utils

public class Logger {
    public fun log(message: String) = println("LOG: $message")
}

// File 2: com/zetcode/Main.kt
package com.zetcode

import com.zetcode.utils.Logger

fun main() {
    val logger = Logger()
    logger.log("Application started") // Output: LOG: Application started
}

Logger 类及其 log 方法是公共的,可以从不同的包访问。Main.kt 文件导入 Logger 类以使用它。

在继承中为公共

从类继承时,父类的公共成员在子类中仍然是公共的,除非使用不同的可见性修饰符进行重写。

InheritancePublic.kt
package com.zetcode

open class Vehicle {
    public open fun start() = println("Vehicle started")
}

class Car : Vehicle() {
    override fun start() = println("Car started")
}

fun main() {
    val car = Car()
    car.start() // Output: Car started
    
    val vehicle: Vehicle = car
    vehicle.start() // Output: Car started
}

start() 方法在 Vehicle 中是公共的,在 Car 中仍然是公共的。重写不会更改可见性。Car 实例和 Vehicle 引用都可以调用该方法。

公共接口

接口成员在 Kotlin 中默认为公共。您不能将它们声明为私有或受保护。public 修饰符对于接口成员是多余的。

PublicInterface.kt
package com.zetcode

interface Drawable {
    fun draw() // Implicitly public and abstract
    
    public fun resize() { // Explicit public (redundant)
        println("Resizing")
    }
}

class Circle : Drawable {
    override fun draw() = println("Drawing circle")
}

fun main() {
    val circle = Circle()
    circle.draw() // Output: Drawing circle
    circle.resize() // Output: Resizing
}

Drawable 接口中的 draw() 和 resize() 都是公共的。resize() 上的显式 public 修饰符是多余的,因为接口成员默认为公共。

公共可见性的最佳实践

来源

Kotlin 可见性修饰符文档

本教程深入介绍了 Kotlin 的 public 关键字,展示了它与类、函数、属性和接口的用法。我们探讨了各种场景,包括默认可见性、显式声明和继承。正确使用可见性修饰符有助于创建良好封装和可维护的代码。

作者

我叫 Jan Bodnar,是一位充满激情的程序员,拥有多年的编程经验。自 2007 年以来,我一直在撰写编程文章。到目前为止,我撰写了 1400 多篇文章和 8 本电子书。 我拥有超过八年的编程教学经验。

列出 所有 Kotlin 教程