Kotlin – 为什么必须在 sub 类 中传递参数值?

Kotlin – Why parameter values have to be passed in sub classes?

我的代码:

open class Club(name: String, country: String)

class FemaleClub(): Club()

var femaleClub = FemaleClub("Blue", "Australia")

为什么上面的代码不可以?

为什么会报错

no value passed for parameter name

no value passed for parameter country

在我的子类中?这些值是在我启动 femaleClub.

时设置的

您的代码存在一些问题:

  • FemaleClub 没有接受两个参数的构造函数,即使基础 class 有一个。

  • 继承class的主构造函数应该调用基础class的主构造函数。因为你的基础 class 接受两个不可为 null 的参数,你必须将它们提供给它,否则你的代码将无法编译。

可以通过以下方式解决这些问题:

class FemaleClub(name: String, country: String): Club(name, country) {
}

FemaleClub 中,您没有指定应该传递给 Club 的内容作为它的 2 个 String 参数,namecountry.

并且您没有在任何地方指定 FemaleClub 将 2 个字符串作为构造函数参数,因此最后一行也不起作用。

在您的示例中,父级 class Club 具有 主构造函数 ,根据语言规范,必须从 辅助构造函数中调用子class的相同class或主构造函数的构造函数初始化主构造函数[=42]中定义的参数=].如果你不想从子class调用父class的主构造函数,你有几个选择:

  1. 主构造函数的参数设置默认值:

    open class Club(name: String = "DefaultName", country: String = "Country") {
    }
    

    在这种情况下,您将无法使用参数 主构造函数 调用:

    // this is not possible
    var femaleClub = FemaleClub("Blue", "Australia")
    
  2. 在父 class 中创建 次构造函数 调用 主构造函数 :

    open class Club(name: String, country: String) {
    
        constructor(): this("Name", "Country")
    }
    

    但您也无法调用 FemaleClub("Blue", "Australia").

为了能够使用子class FemaleClub("Blue", "Australia") 的参数调用构造函数,您需要在子[=55] 的主构造函数 中显式定义它们=] 并调用父级的主构造函数,即:

class FemaleClub(name: String, country: String): Club(name, country) {}

关于 Kotlin 类 和继承,请阅读此处 Classes and Inheritance and here Kotlin Inheritance

您至少可以使用四种方法来获得您想要的:

第一种方法(default values):

open class Club(var name: String = "Blue", var country: String = "Australia") {  }

public class FemaleClub(): Club() {  }

fun main() { 
    var femaleClub = FemaleClub()
    println("RESULT: ${femaleClub.country}")
}

// RESULT: Australia

第二种方法(passing values):

open class Club(var name: String, var country: String) {  }

class FemaleClub(): Club("Green", "NZ") {  }

fun main() {
    var femaleClub = FemaleClub()
    println("RESULT: ${femaleClub.country}")
}

// RESULT: NZ

第三种方法(init block):

open class Club(name: String, country: String) {  

    var name: String = "Blue"
    var country: String = "Australia"

    init {
        this.name = name
        this.country = country 
    }
}

class FemaleClub(): Club("Green", "NZ") {  }

fun main() {
    var femaleClub = FemaleClub()
    println("RESULT: ${femaleClub.country}")
}

// RESULT: NZ

第四种方法(class sec.constructor):

open class Club {  

    var name: String
    var country: String

    constructor(name: String = "Blue", country: String = "Australia") {
        this.name = name
        this.country = country
    }
}

class FemaleClub(): Club() {  }

fun main() {
    var femaleClub = FemaleClub()
    println("RESULT: ${femaleClub.country}")
}

// RESULT: Australia

您需要从要继承的 class 调用构造函数 (primary/secondary)。

Club只有一个构造函数,主构造函数。它需要两个字符串作为参数。 Club 没有空构造函数。

所以,它不能被调用为Club()

我会提出两个更改。

1) 制作 Club 属性的 namecountry

open class Club(name: String, country: String)

2) 在FemaleClub的主构造函数中声明参数

由于您希望能够在实例化 FemaleClub 时为 namecountry 指定值,因此最好给出 [=18= 的主构造函数] namecountry 作为参数。

此外,我建议在传递值时使用命名参数,因为您很容易混淆这两个字符串(导致将名称作为国家/地区传递,将国家/地区作为名称传递。

class FemaleClub(name: String, country: String): Club(name = name, country = country)