Kotlin接口属性:只需要公共getter而不需要公共setter

22

我正在尝试创建一个接口,它强制其派生类具有特定属性,但仅具有公共getter。由于我不希望允许外部对其进行更改,因此我不希望它实现公共set。

interface Transaction{
   var transferDate: Date get //I only require a get, no set
}

class MoneyTransaction(){
   override var transferDate: Date get private set 
/*private set does not work*/
}

在您的情况下,您可以将属性定义为val,这足够了吗? - Luciano Ferruzzi
不,很遗憾不能这样做,因为我仍然需要能够在派生类中私有地更改该值。 - Matthias Hofmarcher
1
当实现属性时,您可以将其设置为 var - Slaw
在接口中将其实现为val是正确的方法。派生类可以有私有后备var字段,并通过接口getter公开该值。 - Pawel
因此,与其他类的接口仅用于读取值,我会定义一个函数来代替,并让实现它的类决定如何提供该值。 - Luciano Ferruzzi
哦,谢谢,我没注意到我可以用 var 覆盖一个 val。 - Matthias Hofmarcher
2个回答

57

属性是一种访问某些数据的方式。您将拥有一个getter,如果该属性是可变的,则还将拥有setter。因此,您可以使用var属性覆盖任何已声明的val属性:

interface Transaction {
   val transferDate: Date
}

class MoneyTransaction: Transaction {
   override lateinit var transferDate: Date
       private set 
}

请注意,如果您使用对象进行初始化,则不需要将属性设置为lateinit var;我只是添加了它以便让您的示例编译正确。


谢谢兄弟!完美无缺。 - Zacharias Hadjikyprianou

4

除了 @tynn 的 有用的回答,在我的情况下,我只需要一个访问来自其他源的数据的访问器。对于这种情况,考虑到使用getter初始化值,可以使用val代替lateinit var,并且不需要指示private set

作为与其他内容相符的示例:

interface Transaction {
   val transferDate: Date
}

class MostRecentTransaction(private val repo: AccountRepository) : Transaction {
   override val transferDate: Date
      get() = repo.transactions.first.transferDate
}

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