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

时间:2019-01-27 00:29:43

标签: class kotlin

我的代码:

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

class FemaleClub(): Club()

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

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

为什么会出现错误

  

未传递参数名称的值

  

未传递参数国家/地区的值

在我的子类中?这些值是在我启动femaleClub时设置的。

5 个答案:

答案 0 :(得分:2)

在您的示例中,父类Club具有主要构造函数,根据语言规范,必须从同一类的次要构造函数或<子类的strong>主要构造函数来初始化在主要构造函数中定义的参数。如果您不想从子类中调用父类的主要构造函数,则有两种选择:

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

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

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

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

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

    但是您也无法拨打FemaleClub("Blue", "Australia")

要能够使用子类FemaleClub("Blue", "Australia")的参数调用构造函数,您需要在子类的主要构造函数中明确定义它们,并调用父级的主要构造函数,即:

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

答案 1 :(得分:1)

您的代码存在一些问题:

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

  • 所继承类的主要构造函数应调用基类的主要构造函数。因为您的基类接受两个不可为空的参数,所以您必须为其提供两个参数,否则您的代码将无法编译。

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

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

答案 2 :(得分:1)

关于Kotlin类和继承,请在此处Classes and Inheritance和此处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

答案 3 :(得分:0)

FemaleClub中,您没有指定应传递给Club的2个Stringname参数。

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

答案 4 :(得分:0)

您需要从要继承的类中调用构造函数(主要/次要)。

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

因此,它不能作为Club()调用。

我会提出两个更改。

1)设置name个属性的countryClub

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

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

由于您希望能够在实例化name时为countryFemaleClub指定值,因此最好为FemaleClub { {1}}和name作为参数。

另外,我建议在传递值时使用命名参数,因为您可以轻松地将两个字符串混合在一起(导致将名称作为国家传递,将国家作为名称传递。

country