Kotlin构造方法梳理

Kotlin主从构造方法梳理

1. 主构造方法

​ Kotlin中有个专有名词叫做主构造方法(primary construcor),其实很好理解,但弄清楚这个词是理清Kotlin中构造方法的前提。所谓主构造方法,就是在类定义的第一行的类名后面添加( ),即以类名加括号的表达方式来表示主构造方法。

	class User(val name: String = “Bob") {
    ...
  }

2. 两种构造方式

​ Kotlin中的构造方式可以归纳为两类:

  1. 单一个主构造方法

    这种构造包含Java中构造方法的两种形式

    • 只有一个构造方法
    • 多个重载参数的的构造方法

    通过在主构造方法中添加参数,可以自动在类中添加相应的属性和默认值,这种方式可以以简单的方式实现Java中需要多个构造方法重载接受多个参数的用例,可以涵盖大部分曾经需要多个构造方法的情形。当主构造方法中每一个参数都存在默认值时,会自动生成无参的构造方法。

  2. 有多个并列的构造方法

    上述构造方式虽然涵盖了大部分我们需要重载构造方法的情形,但当我们需要根据不同的参数提供不同的初始化方法时我们需要提供完整的构造方法。Kotlin提供了多个并列的构造方法的形式来满足这种需求:

    	class User{
        constructor(name: String) {
          ...
        }
        
        constructor(id: Long) {
          ...
        }
      }
    

    与主构造方法相应的,我们将使用constructor的构造方法称为从构造方法(secondary constructor),注意在这种构造方式中,我们不能在constructor的参数中通过val或var来为类添加相应的属性。使用这种构造方式就与Java中的构造方法颇为类似了,只不过我们用constructor关键字取代了类名。

no
yes
是否根据参数提供不同初始化方式?
单一主构造方法
多个并列构造方法

3. 一主多从的构造方式

​ 在Kotlin中由于语法的原因可以构造出一主多从的奇葩构造方式:

	class User(val name: String = "Bob") {
    init{
      ...
    }
    
    constructor(id: Long) : this(){
      ...
    }
    
    constructor(id: Long, email:String)this() {
      ...
    }
  }

能够造出这种方式大多还是因为根据参数的不同提供多种初始化方式,与上述的方法2实现的功能类似,然而因为主构造方法不存在方法体,只能使用init,所以这种构造方式不如使用多个并列构造方法的方式直观,徒增了阅读难度,并不推荐使用这种方式。在主从构造方法混用的情况下,从构造方法必须通过":"调用主构造方法。主构造方法先于从构造方法执行。

但使用这种方式在需要多个构造方法,部分方法根据参数不同提供不同初始化方法,部分方法仅仅提供参数重载时,也能提供一定程度上的简化,即通过主构造方法省略掉重载参数的构造方法。

4. init关键字

​ init关键字称为初始化语块,主要是为了弥补主构造方法没有方法体的缺陷而存在的,我们将需要初始化的内容放在init语块中。

​ 在Java中我们通常会将每个构造方法都会掉用到的共同代码提取到一个方法中,在Kotlin中init语块可以起到这个方法的作用,init并不依托于主构造方法存在,在使用多个从构造方法并列的形式中,依然可以通过init来执行通用代码,而且init中的代码会先于从构造方法执行。

5. constructor关键字

​ 我们通过constructor关键字来表示从构造方法。

​ 在主构造方法中我们需要constructor关键字与可见性修饰符一起使用来设置构造方法的可见性:

	class User private constructor(val name: String) {
		...
	}

6. Kotlin中的继承

​ 在Kotlin中实质上是对类的继承,而表现形式是对父类构造方法的继承,我们需要选取使用合适的父类构造方法,例如,在主构造方法中进行继承:

	class User(name: String) : Person(name) {
		...
	}

而在从构造方法的继承形式上,我们依然需要选择继承父类方法:

class User : Person {
    constructor(name: String) : super(name) {

    }

    constructor(name: String, id: Long) : super(name, id) {

    }
}

当然,如果不使用super,可以选择部分构造方法使用使用this调用自己已经继承了父类构造方法的构造方法。

主从混用的形式以此类推,不再赘述。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章