Kotlin构造函数中的另一个组成部分 ——次构造函数。
其实你几乎是用不到次构造函数的,Kotlin提供了一个给函数设定参数默认 值的功能,基本上可以替代次构造函数的作用,但是可以探讨一下括号问题在次构造函数上的区别。
你要知道,任何一个类只能有一个主构造函数,但是可以有多个次构造函 数。次构造函数也可以用于实例化一个类,这一点和主构造函数没有什么 不同,只不过它是有函数体的。 Kotlin规定,当一个类既有主构造函数又有次构造函数时,所有的次构造函 数都必须调用主构造函数(包括间接调用)。这里我通过一个具体的例子 就能简单阐明,代码如下:
class Student(val sno: String, val grade: Int, name: String, age: Int) : Person(name, age) { constructor(name: String, age: Int) : this("", 0, name, age) { } constructor() : this("", 0) { } }
次构造函数是通过constructor关键字来定义的,这里我们定义了两个次 构造函数:
第一个次构造函数接收name和age参数,然后它又通过this关 键字调用了主构造函数,并将sno和grade这两个参数赋值成初始值;
第二 个次构造函数不接收任何参数,它通过this关键字调用了我们刚才定义的 第一个次构造函数,并将name和age参数也赋值成初始值。
由于第二个次 构造函数间接调用了主构造函数,因此这仍然是合法的。 那么现在我们就拥有了3种方式来对Student类进行实体化,**分别是通过不 带参数的构造函数、通过带两个参数的构造函数和通过带4个参数的构造函数,**对应代码如下所示:
val student1 = Student() val student2 = Student("Jack", 19) val student3 = Student("a123", 5, "Jack", 19)
那么接下来我们就再来看一种非常特殊的情况:类中只有次构造函数,没有主构造函数。这种情况真的十分见,但在Kotlin中是允许的。当一个类没有显式地定义主构造函数且定义了次构造函数时,它就是没有主构造函数的。我们结合代码来看一下:
class Student : Person { constructor(name: String, age: Int) : super(name, age) { } }
注意这里的代码变化,首先Student类的后面没有显式地定义主构造函数,同时又因为定义了次构造函数,所以现在Student类是没有主构造函数的。那么既然没有主构造函数,继承Person类的时候也就不需要再加上括号了。
另外,由于没有主构造函数,次构造函数只能直接调用父类的构造函数, 上述代码也是将this关键字换成了super关键字,这部分就很好理解了, 因为和Java比较像