【问题标题】:Kotlin protected property can not be accessed in other module无法在其他模块中访问 Kotlin 保护的属性
【发布时间】:2025-12-27 15:30:13
【问题描述】:

就在我以为我理解它的时候,我得到了以下问题。

我在另一个模块中有一个基类(这里称为基类)

看起来是这样的:

open class BaseTest {
    companion object {
        lateinit var baseTest: BaseTest
    }
    protected open var someProperty: String? = "base"
}

我想设置该属性并使其受到保护,以便我在另一个模块中的扩展类可以访问它。

class Extended: BaseTest() {

    fun extendedCall() {
        BaseTest().someProperty = "extended"
        baseTest.someProperty = "extended"
    }
}

但是,无论是静态属性还是直接属性都无法访问,并指出以下错误:

Cannot access 'someProperty': it is protected in 'BaseTest'

但是由于 BaseTest() 的扩展固有特性,它不应该是可访问的吗?我的意思是受保护的定义是“声明仅在其类及其子类中可见”所以我错过了什么?它甚至不能在同一个模块中工作,所以这不是原因。

我错过了什么?

【问题讨论】:

    标签: kotlin module protected access-modifiers


    【解决方案1】:

    我相信 protected 修饰符在 Kotlin 中的工作方式并非如此。

    documentation 说:

    protected 修饰符不可用于*声明。

    但我同意它写的很混乱。看来文档通过this 关键字更侧重于外部/内部类关系。

    【讨论】:

    • 谢谢,我想我忘记了有什么不同并在我的脑海中“发明”了一些东西。谢谢!
    【解决方案2】:
        BaseTest().someProperty = "extended"
    

    在这里,您通过调用构造函数BaseTest() 创建一个新的 BaseTest 对象,并且您不能访问 其他 BaseTest 对象的受保护属性。

        baseTest.someProperty = "extended"
    

    静态 BaseTest 对象也是另一个对象,而不是扩展对象本身。

    受到保护只是让事情成为可能

        someProperty = "extended"
    

    或同等的

        this.someProperty = "extended"
    

    即访问this对象的属性。

    【讨论】:

    • 啊,我明白了,boing。多么初学者的错误。当然,所以......只有类本身可以改变它自己的,但不能改变同类型的。 :D
    • @TobiasReich 是的,完全正确
    • 谢谢,是的,我必须承认我很少在 Kotlin 中使用 protected 并且忘记了它是如何使用的(特别是因为我记得有一些与基本 Java0 不同的东西。非常感谢您的快速回答。跨度>
    • 但是愚蠢的问题,有没有办法只允许我的扩展类设置该属性?我需要设置它,但要设置该类型的另一类。并且所有解决方案都将是丑陋的(例如,需要该类的实例作为参数等)
    • @TobiasReich 恐怕这对您来说可能不是一个选择,但有可能将其标记为internal 并确保基类和扩展在同一个模块中并且是唯一的类在模块中。否则我不会知道。可能值得在这里提出一个新问题