来自the documentation:
Kotlin 中的类可以有一个主构造函数和一个或多个辅助构造函数。主构造函数是类头的一部分:它位于类名(和可选类型参数)之后。
这是主构造函数的示例:class MyClass constructor()
仅当您想指定可见性修饰符 (default is public) 和/或注释时,关键字 constructor 才是强制性的,因此以下所有替代方案都是等效的:
class MyClass public constructor()
class MyClass constructor()
class MyClass()
class MyClass // parenthesis can be omitted if no argument is provided
显然,如果这是您想要的构造函数,则更简洁的版本优于更冗长的版本。
除了主构造函数之外,您还可以有零个、一个或多个辅助构造函数。辅助构造函数必须直接或间接委托给主构造函数 - 通过调用另一个辅助构造函数 - 示例:constructor(...) : this(...)。
如果您的类没有指定任何主构造函数,则任何辅助构造函数都必须委托给超类。示例:例如constructor(...) : super(...).
如果您不指定任何主构造函数或辅助构造函数,那么您的类将有一个不带参数的隐式默认公共构造函数(如在 Java 中)。
所以,回答你的问题:
constructor 在class MyClass constructor(): Fragment() 上的含义是什么?
它声明了主构造函数,但鉴于您没有指定任何可见性修饰符,也没有任何注释,它可以被省略。这同样适用于括号,因此它可以重写为class MyClass : Fragment()(注意: Fragment() 位声明您的类扩展Fragment 并指定MyClass 的默认构造函数应调用其父级的空构造函数(更多细节@ 987654323@)
为什么我必须输入this()?
如上所述,这对于辅助构造函数是必需的。
编辑
正如我在下面的评论中所解释的,在代码的第一个 sn-p 中,您是:
- 定义辅助构造函数(
constructor(parent: Activity))
- 未定义主构造函数。那是因为你有一个辅助构造函数,但在你的类定义之后没有括号(即
class MyClass() 或class MyClass constructor() - 它们是等价的,如上所述),所以 Kotlin 不会为你生成默认的空主构造函数
- 您的类正在扩展
Fragment,并且您正在调用父类的构造函数作为类签名的一部分。这需要您的类的主要构造函数,如您所面临的错误突出显示:Supertype initialization is impossible without primary constructor。
如何解决问题?
一种可能的方式是您所做的,即同时定义主构造函数和辅助构造函数。但是,您可以通过 2 种方式创建 MyClass 的实例:传递或不传递父 Activity。这大致相当于下面的 Java 代码:
class MyClass extends Fragment {
private Activity parent;
public MyClass() {
super()
}
public MyClass(Activity parent) {
super()
this.parent = parent;
}
}
您可能不想在没有父 Activity 的情况下构建该类。如果是这种情况,只需摆脱辅助构造函数——你不需要它——并创建一个接受任何你需要的参数的主构造函数。
示例:class MyClass(val parent: Activity) : Fragment()。这是定义主构造函数的一种非常简洁的方法,该构造函数接受输入中的 Activity 并将该参数分配给名为 parent 的实例变量; val 意味着 parent 将是只读的(即 Kotlin 将生成 getter 但不生成 setter),但如果您需要实例变量是可变的,则可以使用 var 代替(即 Kotlin 将生成 getter 和二传手)。
这大致相当于下面的Java代码:
class MyClass extends Fragment {
private Activity parent;
public MyClass(Activity parent) {
this.parent = parent;
}
}