首页 > 解决方案 > Kotlin:在构造函数中访问非最终属性名称

问题描述

这个问题之前已经在 Stack overflow 中得到了回答,但是由于我是 Kotlin 的新手,所以我不明白这一点。如果有人能告诉我下面的代码(用简单的语言)有什么问题以及我如何解决这个问题,那将非常有帮助。我在 Country 类的“名称”属性下收到来自 IntelliJ IDEA 的警告,提示我正在尝试访问构造函数中的非最终属性名称。那有什么问题?

open class Country (n : String? = null)
{
    open var name : String? = n

    init {
        if (n==null)
        {
            this.name = "Unknown Country"
        }
        else
        {
            this.name = n
        }
    }

    fun printCountryName()
    {
        println("Country Name : ${this.name}")
    }

}

class India constructor(n: String? = null, p: Int, g: Double ): Country(n)
{
    override var name : String? = "India"

}

标签: kotlin

解决方案


您需要记住,属性不仅仅是字段。它们是字段 + getter/setter。通过声明让您的子类name更改. 然后,任何子类都可以这样做:opensetName()

class MyCountry : Country("foo") {
    override var name: String?
        get() = null
        set(value) {}
}

这样,构造函数Country将无法设置名称。

open用于更改实现,而不是更改存储值。如果您需要一些默认值,则只需将其设置为正常:

class India constructor(p: Int, g: Double ): Country("India")

要解决您的问题,您只需删除openfrom name,因为从您的示例来看,您似乎并不真正需要它。

更新

此外,我在您的代码中看到了潜在的错误/错误:

  1. 如果您在构造时检查 Country name 的可空性并将 null 替换为“Unknown Country”,那么为什么nameproeperty 是String?而不是String?似乎你不想在那里有空值,但仍然允许它们。
  2. 我想更改现有国家/地区的名称没有意义,所以我相信您可以使用val而不是var.

推荐阅读