当前位置: 首页 > 知识库问答 >
问题:

Kotlin中的属性名称和主构造函数参数名称相同

施靖
2023-03-14

我不太清楚kotlin是如何管理属性名和主构造函数参数名的。如果我写了相同的属性名和参数名,那么kotlin编译器会给出一个错误。

class Student(name : String, roll : Int){
    val name: String

    init {
        name = "Asif"
    }
}

它给出了这个错误。

> Error:(9, 5) Kotlin: Property must be initialized or be abstract
> Error:(12, 9) Kotlin: Val cannot be reassigned

但是,当我更改属性的名称val name:String或更改主构造函数的参数名称name:String时,代码将工作并编译。

这将工作或编译罚款。

class Student(pName : String, roll : Int){
    val name: String

    init {
        name = "Asif"
    }
}

这背后的原因是什么?为什么主构造函数的参数名和属性名不能相同?

共有3个答案

陶弘业
2023-03-14

答案是由其他人提供的,但为了澄清这些版本:
(a)

class Student1(name : String, roll : Int){
    val name: String

    init {
        this.name = "Asif"
    }
}

(b)

class Student2(name : String, roll : Int){
    val name: String = "Asif"
}


(c)

class Student3(val name : String = "DefaultName", roll : Int)  


Student1Student2是完全等效的,但Student3不是:
如果运行以下代码:

val s = Student1("Nick", 2)
println(s.name)
val s2 = Student2("Nick", 2)
println(s2.name)
val s3 = Student3("Nick", 2)
println(s3.name)

你会看到:

Asif
Asif
Nick
赫连俊悟
2023-03-14

Init block提供来自默认构造函数的参数。要分配对象的名称字段,必须显式使用此选项。姓名

class Student(name : String, roll : Int){
    val name: String

    init {
        this.name = "Asif"
    }
}

但更多的kotlin方法是直接在构造函数中声明具有默认值的字段:

class Student(val name : String = "DefaultName", roll : Int){ }
夏奕
2023-03-14

主构造函数参数在属性初始化器和初始化器块中可用(这就是主构造函数的特殊之处)。

在您的init块中,name引用了构造函数参数,它和所有其他函数参数一样,不能重新分配。这是第二个错误。第一个是出于同样的原因,现在您的属性没有在任何地方初始化。

如果要初始化属性,仍然可以将其称为this。姓名

class Student(name : String, roll : Int){
    val name: String

    init {
        this.name = "Asif"
    }
}
 类似资料:
  • 我想问一下java编程语言,具体到构造函数。假设我们有一个类测试,在那里我们测试整个程序,和类点,在那里定义构造函数(集和获取方法btw)。类行: 类点: 现在,如果我在构造函数中输入类点的名称,那将是一个错误:

  • 问题内容: 说我以某种方式从另一个类获得了对象引用: 现在,我可以获取该对象的类: 现在,我可以获得该类的所有构造函数: 现在,我可以循环每个构造函数: 这已经为我很好地总结了构造函数,例如,构造函数public Test(String paramName)显示为public Test(java.lang.String) 但是,我不想获取类的类型,而是要获取参数的名称。在这种情况下,为“ para

  • 问题内容: 我有一个疑问,因为@Entity和@Table中都存在name属性 例如,允许名称属性具有相同的值 我也可以在同一班上使用不同的名字 谁能告诉我这两者之间有什么区别,为什么我们两者都具有相同的属性? 问题答案: DB 因此,在第一种情况下,表和实体将具有相同的名称,这将允许您在编写HQL或JPQL时以与实体相同的名称访问表。 在第二种情况下,编写查询时,您必须使用 @Entity中提供

  • 问题内容: 在Swift中,调用第一个参数时会使用参数名称。为什么不使用名字? 使用Swift手册的变体; 这会起作用; 但这给了我“调用中的外部参数标签’amount’” 是否有这个原因,或者这是“按其原样”的事物之一? 问题答案: 这是遵循Objective-C习惯的惯例,第一个参数的名称与方法名称结合在一起。这是一个例子: 您可以像这样调用方法: 通过将参数的名称合并到方法的名称中,可以使阅

  • 从一个对象的自身(是否继承可选)可枚举属性返回一个函数属性名称数组。 使用 Object.keys(obj) 来迭代对象的自身属性。 如果 inherited 是 true ,则使用 Object.get.PrototypeOf(obj) 来获得对象的继承属性。 使用 Array.filter() 只保留那些函数的属性。 省略第二个参数 inherited,默认情况下不包含继承的属性。 const

  • 我创建了这个扩展方法,它从一个KClass获取所有属性 扩展方法 示例用法 结果 val公司。演示。富。酒吧:科特林。内景 val公司。演示。富。巴兹:科特林。一串 VARcom.demo.Foo.boo:kotlin。字符串? 如何修改此扩展方法以仅返回在主构造函数中声明的属性? 预期成果 val公司。演示。富。酒吧:科特林。内景