Kotlin:子构造函数如何使用其父类的次要构造函数?

13

例如,我们有这个父元素:

open class Parent(val id: Int, val name: String?) {
    constructor() : this(-1, null)
}

一个子类必须有一个带两个参数的构造函数和一个无参构造函数,就像父类一样:

Translated:

A child class must have a two-parameter constructor and an empty constructor, just like the parent class.

class Child(id: Int, name: String?) : Parent(id, name) {
    constructor() : super() // syntax error
}

一个子构造函数如何使用其父类的次要构造函数?

我知道可以通过实现一个子构造函数并传入与父构造函数相同的值来达到此目的,但这不仅似乎是冗余的,而且通常情况下我的子类具有额外的参数作为主构造函数的一部分,但不需要中间构造函数(具有不包括所有额外参数的参数)。以下是一个实现了这种方式的示例子类,以防我没有表述清楚:

class Child(id: Int, name: String?) : Parent(id, name) {
    constructor() : this(-1, null) // no syntax error, but redundant
}

请添加您收到的错误信息。 - voddan
2个回答

13

我认为实现这一点的最佳方式是使用构造函数中的默认参数

class Child(id: Int = -1, name: String? = null) : Parent(id, name)

根据你在Parent类上的影响力,甚至可能

class Parent(val id: Int = -1, val name: String? = null)

不过这个方法有一个“缺点”:你会得到三个不同的构造函数。但我认为这并不是问题,因为你必须处理id=-1name=null的情况。

此外,我认为你的解决方案

class Child(id: Int, name: String?) : Parent(id, name) {
    constructor() : this(-1, null) 
}

不管怎样,"冗余"或者说是不好的,实际上体现了高度的表达和明确性,这样读者才能够准确地理解你的意图。


11

首先,由于Parent类没有被声明为open,因此无法扩展该类。

其次,如果一个类已经声明了主构造函数,你就不能通过super关键字调用超类的构造函数。

另一方面,如果你想通过super关键字调用超类的构造函数,你需要将主构造函数变成辅助构造函数,例如:

class Child : Parent {
  constructor(id: Int, name: String?) : super(id, name)
  constructor() : super()
}

另一个选择是让次要构造函数使用 this 关键字调用主要构造函数,但我认为这是不必要的,并且会在超类的次要构造函数中产生重复参数:

另一种选择是通过 this 关键字让次要构造函数调用主要构造函数,但我认为这是不必要的,因为它会在父类的次要构造函数中拥有重复的参数:

class Child(id: Int, name: String?) : Parent(id, name) {
  constructor() : this(-1, null);
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接