我正在创建一个非常简单的kotlin程序,并且看到父类的行为很奇怪。
代码是:
fun makeSalt(name:String) = Spice(name, "non-spicy")
fun main(args: Array<String>) {
var salt : Spice = Spice("salt", "non-spicy")
println("Salt heat = ${salt.heat}")
val spicelist = listOf<Spice>(
Spice("salt", "non-spicy"),
Spice("turmeric", "mild"),
Spice("Pepper", "hot"),
Spice("Chilli", "hot"),
Spice("Sugar", "non-spicy")
)
val mildSpices = spicelist.filter{it.heat <=5}
val salt2 = makeSalt("rock salt")
val bhoot : SubSpice = SubSpice("bhoot", "hot")
}
open class Spice(open var name:String, open var spiciness:String = "mild" ){
var heat : Int = 5
get() = when (spiciness){
"mild"->5
"hot"->10
"non-spicy"->1
else -> 0
}
init{
if(spiciness === null) {println("spiciness is null")}
else println("Spiciness of ${name} = ${spiciness}; heat = ${heat}")
}
}
class SubSpice(override var name:String, override var spiciness:String = "hot") : Spice(name, spiciness){
}
执行此程序时,输出为:
Spiciness of salt = non-spicy; heat = 1
Salt heat = 1
Spiciness of salt = non-spicy; heat = 1
Spiciness of turmeric = mild; heat = 5
Spiciness of Pepper = hot; heat = 10
Spiciness of Chilli = hot; heat = 10
Spiciness of Sugar = non-spicy; heat = 1
Spiciness of rock salt = non-spicy; heat = 1
spiciness is null
如您所见,当我创建子类的对象时,父类的变量spiciness
变为null。有人可以解释为什么吗?我希望它为null,因为它也具有默认参数"mild"
答案 0 :(得分:5)
在不覆盖任何getter / setter方法时,您正在使用open var
。
您要引入奇怪的初始化冲突,因为Spice.init
(父类构造函数)在SubSpice.init
之前被调用,并且通过覆盖字段,它们不再与父构造函数一起初始化-而是一旦{ {1}}已构建。
从父类的变量和子构造函数的Subspice
删除open
关键字,这样字段将在override var
类中正确初始化,并且其Spice
块应成功运行
答案 1 :(得分:2)
要在Pawel的答案中添加其他信息:
如果使用open
覆盖属性,则基类中的init块将在初始化派生属性之前运行。
查看文档:{{3}}
因此,如果我们像Pawel建议的那样更改代码,最终将得到如下结果:
fun main(args: Array<String>) {
Spice("salt", "non-spicy")
Spice(name="spice")
SubSpice(name = "bhoot", spiciness = "hot")
SubSpice(name="subspice")
}
open class Spice(var name:String, var spiciness : String = "mild" ) {
var heat : Int = 5
get() = when (spiciness){
"mild"->5
"hot"->10
"non-spicy"->1
else -> 0
}
init{
if(spiciness === null) {println("spiciness is null")}
else println("Spiciness of ${name} = ${spiciness}; heat = ${heat}")
}
}
class SubSpice(name: String, spiciness : String = "hot") : Spice(name, spiciness) {
}
哪个输出:
Spiciness of salt = non-spicy; heat = 1
Spiciness of spice = mild; heat = 5
Spiciness of bhoot = hot; heat = 10
Spiciness of subspice = hot; heat = 10