【问题标题】:Kotlin constructors: primary and secondaryKotlin 构造函数:主要和次要
【发布时间】:2017-06-30 09:58:46
【问题描述】:

刚开始使用 Kotlin,您可以在其中拥有 primary 构造函数和 secondary 的。这个问题听起来很简单,但我找不到答案(我已阅读文档中的“构造函数”部分 ) - 为什么?

基本上,我试图了解主要和次要背后的想法是什么。以及它们的使用方式有什么区别(好像没有,为什么要分开)?

【问题讨论】:

  • 一个主要的区别是所有的辅助构造器最终都必须委托给主构造器。
  • @OliverCharlesworth 谢谢!这听起来如此合乎逻辑和简单,以至于我无法理解为什么我从一开始就没有得到它。

标签: constructor kotlin


【解决方案1】:

主构造函数

  • 一个 Kotlin 类只能有一个主构造函数。
  • 主构造函数提供了一种初始化类成员属性的简单方法。
  • 它采用逗号分隔的参数列表,并在类名之后声明为标题的一部分。
// How to declare a primary constructor
class Student constructor(
     firstName:String,
     lastName:String
){
}

// We can omit constructor keyword if the primary constructor 
//does not have any annotations or visibility modifiers

class Student(
     firstName:String,
     lastName:String
){
}

fun main(){
     val student1 = Student("Helen", "trump")
}
  • 由于 Kotlin 中的主构造函数具有受约束的语法,它的定义仅用于声明类属性,它不接受任何逻辑或代码。因此,为了填补这一空白,Kotlin 提供了一个灵活的 init 块 概念,我们可以在其中添加更多自定义代码来执行一些逻辑!
class Student(
    firstName:String,
    lastName:String
){
   init{
       println("Welcome to the student profile")
   }
}
  • 这些初始化程序块在调用主构造函数之后和任何辅助构造函数之前执行。

二级构造函数

  • 一个 Kotlin 类可以有一个或多个以及一个或多个二级构造函数。
  • 它们必须以关键字constructor作为前缀。
  • 我们不能像在主构造函数中那样在辅助构造函数中声明类属性。
  • 每个辅助构造函数都必须显式调用主构造函数。我们可以使用 this 关键字来做到这一点。
class Pizza constructor (
    var crustSize: String,
    var crustType: String,
    val toppings: MutableList<String> = mutableListOf()
) {

    // secondary constructor (no-args)
    constructor() : this("SMALL", "THIN")

    // secondary constructor (2-args)
    constructor(crustSize: String, crustType: String) : this(crustSize, crustType, mutableListOf<String>())

    override fun toString(): String = "size: ${crustSize}, type: ${crustType}, toppings: ${toppings}"

}
fun main(args: Array<String>) {
    val p1 = Pizza()
    val p2 = Pizza("LARGE", "THICK")
    val p3 = Pizza("MEDIUM", "REGULAR", mutableListOf("CHEESE", "PEPPERONI"))

    println(p1)
    println(p2)
    println(p3)
}

// output
size: SMALL, type: THIN, toppings: []
size: LARGE, type: THICK, toppings: []
size: MEDIUM, type: REGULAR, toppings: [CHEESE, PEPPERONI]

参考

【讨论】:

    【解决方案2】:

    很明显,这是各种语法差异。但一个主要的概念差异是所有辅助构造函数最终都委托给主构造函数。

    我对此的看法是,主构造函数是用于创建对象的规范接口,而辅助构造函数就像用于转换其他参数集以符合此接口的静态助手。*


    * 请注意,这是个人解释,没有任何官方文档支持!

    【讨论】:

    • 我倾向于同意您的“个人解释”。所有其他差异似乎不需要主要/次要区分。
    【解决方案3】:

    kotlin 主构造函数帮助你编写compact代码:

    • 你可以写没有body的class,例如:data class,例如:

      data class Data(val value:String)
      
    • 如果构造函数上没有注解,则可以省略关键字constructor。反例:

      class Foo @Annotation constructor()
      
    • 它使继承变得简单,例如:

      open class Bar(val value: String);
      
      class Primary(value: String, other: String) : Bar(value)
      
      class Secondary : Bar {
          constructor(value: String, other: String) : super(value)
      }
      
    • 它可以通过关键字by使用委托,但二级构造函数不能使用。

      interface Rule {
          fun apply(value: String): Int
      }
      
      
      open class Policy(rule: Rule) : Rule by rule;
      

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-05-12
      • 2019-01-10
      • 1970-01-01
      • 2019-10-08
      • 1970-01-01
      相关资源
      最近更新 更多