为什么Kotlin有两种类型的构造函数?

时间:2018-07-26 14:57:45

标签: constructor kotlin primary-constructor

Kotlin有两种类型的构造函数,主要和次要的。拥有两种类型的目的是什么?我认为,这会使代码更加复杂和不一致。如果两种类型的构造函数都创建类的对象,则它们对类同样重要。

同时,多个初始化程序也会引起混乱并降低可读性。

3 个答案:

答案 0 :(得分:3)

当您需要将作为构造函数参数传递的值保存到实例的属性时,主要构造函数涵盖了通用的用例。

基本上,主构造函数为声明属性和从构造函数参数初始化属性提供了一种快捷方式。

请注意,您完全可以不使用主构造函数来完成此操作:

class Foo {
    val bar: Bar

    constructor(barValue: Bar) {
        bar = barValue
    }
}

但是,由于这种情况确实经常发生在代码库中,因此Kotlin主要构造函数的作用是在此处减少样板:

class Foo(val bar: Bar)

次要构造函数可以补充或替换主要构造函数,以支持单个类的多个构造例程。

答案 1 :(得分:1)

哲学:主要目的-kotlin是pragmatic语言。它的主要思想是:排除最常见的样板。

在C#/ Java中使用的许多类只有一个具有以下语义的构造函数:

  • 部分参数存储在字段中(具有相同的名称)
  • 构造函数使用部分参数创建其他字段(或进行额外验证)

此外,许多辅助构造函数用于调用具有默认值的主要构造函数(请参见此question for C# language

因此,:要拥有简化的代码(反映本质),您必须具备以下能力:

  • 支持构造函数参数,这些参数将自动存储到字段中(无@POST public void create() throws IOException { String incomingPost = Util.read(getRequestInputStream()); Map[] people = JsonHelper.toMaps(incomingPost); Person newPerson = new Person(); newPerson.fromMap(people[0]); boolean response = newPerson.save(); //Making sure person info is persisted so that it can be Rolled back if (response == true) { throw new InitException("Rollback Transaction"); } render("/system/RestIndex").noLayout().contentType("application/json"); view("jsonResponse", Person.findAll().toJson(true)); }
  • 支持根据构造函数参数创建字段的功能

以上两项都是必需的,因此所有构造函数都具有相同的输入值(因为应初始化所有字段,但是它们在构造函数主体之外设置)。因此,您必须具有主构造函数,它将进行初始化。

在应用了这种逻辑之后,我们得到了主要规则:要涵盖最频繁的类初始化方案,您必须拥有能够定义默认参数值的主构造函数。此外,您应该具有创建辅助构造函数的能力,以覆盖所有其他情况。

所以,我重复主要观点:需要主要的构造函数来涵盖最常见的情况(务实的目的)

答案 2 :(得分:0)

主要构造函数可以定义将哪些参数传递到init块中。例如:

class Foo(a: Bar){
    val b : Bar

    init { 
         b = a // value of "a" is known from primary constructor
    }

    constructor(a: Boo) : this(a.toBar())
}

如果没有显式的主构造函数调用,将无法确定在a中应使用init的哪种值/类型。

主要构造函数和初始化程序块始终在次要构造函数块(doc)之前执行。