Kotlin:在构造函数中访问非final属性名称

4

这个问题在Stack Overflow上已经有了答案,但由于我是Kotlin的新手,我不理解那个答案。如果有人能以简单的语言告诉我下面的代码有什么问题,以及如何修复它,那将非常有帮助。在Country类的'name'属性下,我收到了来自IntelliJ IDEA的警告,说我正在尝试在构造函数中访问非final属性名。这有什么问题吗?

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"

}

It's okay if you don't understand another similar question - just clearly point out what you don't understand. - Someone_who_likes_SE
2
我认为你不应该这样做的原因与Java中构造函数中调用可重写方法有什么问题?的原因相同。 - Slaw
你确定要将 var 设为 open 吗?这似乎没有必要允许子类覆盖该属性。也许你是想让子类赋值给现有的属性?如果不是 open,那么你就不会遇到这个问题。 - Silvio Mayolo
感谢Someone_who_likes_SE、Slaw和Silvio。我想详细阐述我想要实现的内容。假设我只在我的Kotlin文件中创建了一个国家类,并且上面提到的代码一切正常。第二天,我的朋友告诉我,他想创建一个印度类,并想扩展我的类。他的要求是国家名称始终为印度,而不像我的类,用户传递名称参数,然后我在初始化块中执行检查,并根据用户输入设置国家名称为“未知”或基于用户输入的其他内容。 - Sujit Singh
注释(2/2):我在我的Country类中在(var name:String?= n)前面放置了open关键字,因为我的朋友将在他的India类中重写它为“India”。如何确保我不必更改我的Country类代码,并确保我的朋友可以继承我的类的所有属性和函数,并根据他的选择提供自己的实现。 - Sujit Singh
1
为什么不摆脱init块,直接使用val name = n ?: "Unknown Country"呢?然后由子类将适当的名称传递给构造函数。例如,您的朋友可以这样做class India : Country("India")。当然,为每个国家创建一个子类并不是可行的方法(它无法很好地扩展)。如果您需要一个“印度国家”,那么您应该只需执行foo = Country("India") - Slaw
1个回答

1
你需要记住,属性不仅仅是字段。它们是字段加上getter/setter方法。通过将name声明为open,你可以让子类更改setName()的实现。然后,任何子类都可以像这样做:
class MyCountry : Country("foo") {
    override var name: String?
        get() = null
        set(value) {}
}

这样,Country 的构造函数就无法设置名称。 open 是用于更改实现,而不是更改存储的值。如果您需要一些默认值,那么只需像平常一样设置即可:
class India constructor(p: Int, g: Double ): Country("India")

为了解决你的问题,你只需要从name中删除open,因为从你的示例中看来,你似乎并不需要它。 更新 此外,我在你的代码中发现了潜在的错误/bug:
  1. 如果你在构建时检查国家名称是否为空,并用“未知国家”替换空值,那么为什么name属性是String?而不是String?看起来你不想在那里有空值,但仍允许它们。
  2. 我猜更改现有国家的名称没有意义,所以我认为你可以使用val代替var

抱歉给您添麻烦了,能否看一下这个问题 - lazydevpro

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接