编程Kotlin开发者

解释Kotlin中构造函数的可见性和继承的细节:主构造函数和次构造函数有什么区别,继承和可见性修饰符的细节。请提供代码示例和常见错误。

用 Hintsage AI 助手通过面试

答案。

在Kotlin中,任何类可以有一个主构造函数(在类声明中指定)和多个次构造函数(通过constructor)。

  • 主构造函数不能包含声明外的代码(逻辑在init中)。
  • 次构造函数实现额外的初始化选项。
  • 如果父类没有无参数构造函数,子类必须显式调用其构造函数。
  • 可以使用修饰符(privateprotectedinternalpublic)隐藏或限制构造函数的可见性。

主构造函数和次构造函数的示例:

open class Person(val name: String) { constructor(name: String, age: Int) : this(name) { // 次构造函数 } } class Employee : Person { constructor(name: String) : super(name) // 显式super是必须的 }

可见性修饰符:

class Secret private constructor() { companion object { fun create() = Secret() } } val s = Secret.create() // 正常,Secret() - 错误

细节:

  • 如果具有主构造函数的类有参数,则无法在不传递这些参数的情况下继承。
  • 次构造函数必须间接或直接调用主构造函数。
  • 嵌套类无法访问外部类的private构造函数。

带陷阱的问题。

在Kotlin中可以继承一个类而不调用其主构造函数吗?

答案:不可以。在Kotlin中,继承时必须调用父类的至少一个构造函数——要么是主构造函数,要么是次构造函数(通过super())。

示例:

open class A(val x: Int) class B: A // 错误:需要显式调用构造函数A

由于对主题细节的不熟悉而产生的实际错误示例。


故事

在团队中试图禁止直接创建类的对象并将构造函数设置为private。但忘记实现工厂方法。这导致在没有反射的情况下无法测试该类,并阻止了CI。


故事

继承了具有主构造函数的类,必须的参数未在声明子类时传递。直到编译阶段才发现此问题,经过长时间的调试。


故事

使用次构造函数时忘记了所有的次构造函数都必须调用主构造函数。导致对象在没有必要参数的情况下初始化,导致运行时的NullPointerException。