为什么我将userName设为public时出错:
错误:(2,5)Kotlin:平台声明冲突:以下内容 声明具有相同的JVM签名 (getUserName()Ljava /郎/字符串): fun():在User中定义的字符串 fun getUserName():在User
中定义的字符串错误:(4,5)Kotlin:平台声明冲突:以下声明具有相同的含义 JVM签名(getUserName()Ljava / lang / String;): fun():在User中定义的字符串 fun getUserName():在User
中定义的字符串
但是我使userName是私有的正常工作
class User{
/*private*/ var userName: String = "Emily"
fun getUserName(): String{
return userName
}
}
fun main(args: Array<String>){
val User = User()
print(User.getUserName())
}
答案 0 :(得分:4)
通过制作userName
媒体资源public
,Kotlin将为您创建相应的getUserName()
和setUserName()
函数。当它这样做时,编写自己的getUserName()
是多余的 - 具有相同签名的相同函数实际上存在两次 - 并且编译器将不允许它。
如果您希望userName
字段是公共属性(使用生成的getter和setter),那么您也不能自己编写getter。这就足够了:
var userName: String = "Emily"
如果您希望userName
拥有public
getter和private
setter(看起来像您的意图),这就是Kotlin的方法:
var userName: String = "Emily"
private set
最后,您仍然可以在属性上创建自定义访问器(例如,如果您需要额外的逻辑,例如将其返回为小写)。 Kotlin这样做的方式如下:
private var _userName: String = "Emily"
var userName: String
get() = _userName.toLowerCase()
set(value) { _userName = value }
另请注意,您访问该属性的方式因您是从Kotlin还是Java访问而有所不同。从Kotlin,您只需编写user.userName
,但在Java中,您可以编写user.getUserName()
。
答案 1 :(得分:1)
定义var userName
时,您really defining a property,而不仅仅是字段。与属性一起使用隐式getUserName()
和setUserName()
方法。通过添加自己的getUserName()
,您可以自动为Kotlin创建一个阴影。
您可以安全地放弃getUserName()
并使您的字段非私密,它应该可以正常工作。编写代码的惯用方法是这样的:
class User {
var userName: String = "Emily"
}
fun main(args: Array<String>){
val user = User() // Note changed val from User to user.
print(user.userName) // Note, this really calls the getter
}
答案 2 :(得分:1)
在Kotlin中,正在为每个属性创建一个setter和getter(除非可见性禁止它),例如对于您的userName
,其名称恰好与您提供的名称完全相同:getUserName()
。结果是名称冲突。请注意,对于var
,还会生成setter。将val
用于只读属性。
实际上,你不需要像这样明确的吸气剂。只需:
class User{
/*private*/ var userName: String = "Emily"
}
//use property syntax
val user = User()
print(user.userName)
答案 3 :(得分:1)
我只想添加更多关于private
字段的内容。当您使用private
修饰符声明字段时,Kotlin将不会生成getter / setter
class User {
private var userName = "Na"
fun getUserName(): String {
return userName;
}
fun setUserName(v: String) {
userName = v
}
}
当您声明上述方法(getter和setter)时,这些方法将被视为用户定义的方法。