Kotlin系列之主构造方法和初始化语句块

前面我们已经说过类和接口的知识点,今天来看看Kotlin中的主构造方法和初始化语句块。

我们知道在Java中也存在构造方法的概念,也有初始化块的概念。所以今天还是拿Kotlin和Java进行对比学习。

Java中的构造方法和初始化块

在Java中构造方法有以下几点的规则。
1 . 构造方法没有返回值,方法名必须与类名相同

2 . 如果没有显式声明构造方法,Java会给我们生成一个默认的不带任何参数的构造方法

在Java中的初始化块又分为普通初始化块静态初始化块,他们的规则如下。
1 . 普通初始化块在每次对象创建时被调用,静态初始化块只在类被加载时调用,且只会被调用一次

2 . 普通初始化块用来在一个对象创建时初始化其中的一些参数

下面通过代码来简单解释以下上面的规则。

Java代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
package ja;

public class Main {
//静态初始化代码块
static {
System.out.println("类被加载了...");
}

private int value;
private int num;

//普通初始化代码块
{
num = 10;
}

//构造方法用来初始化参数
public Main(int value){
this.value = value;
}

public int add(int other){
return this.value + this.num + other;
}
}

上面都是java的基础知识,写出来主要是方便与Kotlin的进行对比。

Kotlin中的主构造方法和初始化语句块

在Kotlin中也存在和Java中相似的概念,但也又一些差异。
这里有一个概念是主构造方法。在Kotlin中一个类同样可以声明多个构造方法,但Kotlin将他们分为主构造方法从构造方法
主构造方法是一个主要且简洁的初始化类的方法,而且它声明在类的外部,而从构造方法是声明在类的内部。今天我们先说说主构造方法和与之相关的初始化语句块

在Kotlin中构造方法的声明需要使用到constructor关键字,初始化语句块的声明需要使用到关键字init。在Kotlin中构造方法一般是用于传入一些创建类时需要的参数,配合初始化语句块来对类的属性进行初始化。下面用代码来实际说一下。

Kotlin代码

1
2
3
4
5
6
7
8
9
10
//该类的主构造方法需要传入name参数
class User constructor(name: String){
//类的name属性
val name: String

//初始化语句块用于配合构造方法给属性赋初始值
init {
this.name = name
}
}

上面的代码还是很好理解的,其实就相当于把我们的构造方法和类的声明放在了一起。注意上面的this和我们java中的用法是一样的,都是在于构造方法的参数名和类的属性名相同时来区分两者。

当然Kotlin是一门追求简洁的语言,我们可以把上面的代码进一步简化。像下面这样。

Kotlin代码

1
2
3
4
class User (name: String){
//类的name属性
val name = name
}

直接省略了constructor关键字和初始化语句块,直接赋值即可。

当你觉得这样已经够简洁的时候,还有更简洁的,想下面这样。

Kotlin代码

1
class User (val name: String)

直接将val关键字加载构造方法属性前面,就完成了构造方法参数的声明和类属性的声明和赋值,甚至连{}也不需要了。

Kotlin中的构造方法新特性

除了上面简洁的语法,还有很多新特性。我们在前面的文章中说过,一个方法的参数可以又默认值,也可以在传入方法参数时带上参数名使代码可读性更好。由于构造方法也是方法,我们同样可以使用这些特性,就像下面代码描述的那样。

Kotlin代码

1
2
//构造方法参数带默认值
class User (val name: String, val isMan: Boolean = false)

那我们如何使用上面的类呢?

Kotlin代码

1
2
3
4
5
6
fun main(args: Array<String>){
//第二个参数使用了默认值
val user1 = User(name = "Mike")

val user2 = User(name = "Tom", isMan = true)
}

是不是代码简洁清楚了很多呢。

Kotlin构造方法与继承

我们知道在Java中如果我们没有显式声明一个构造方法,就会为我们默认添加一个无参的构造方法,在Kotlin中也是一样的。
那么当我们涉及到继承时,我们该怎么写呢?在Kotlin中当你继承一个类不再只是写出类名就可以了,而是要给你继承类的构造方法同时传入参数j将,就像下面这样。

Kotlin代码

1
2
3
4
5
open class User (val name: String, val isMan: Boolean = false)

class GoogleUser(name: String, val age: Int): User(name){

}

上面的代码中,我们创建GoogleUser这个子类,并且将它的构造方法的name参数传递给了父类的构造方法。同时我们还为子类增加了一个新的属性age
当然,如果我们继承的父类没有指定构造方法,由于有默认构造方法的存在,我们在继承时必须要注意。像下面的代码一样。

Kotlin代码

1
2
3
4
5
open class Father

class Son: Father(){
//...
}

这里我们在继承father类时必须有(),因为这里的意义是构造方法。

我们前面也说过接口是没有构造方法,不能被实例化的,所以就没有(),像下面这样。

Kotlin代码

1
2
3
4
5
interface Clickable

class View: Clickable{

}

写在最后

可以看出Kotlin在模仿Java的一些方面的同时,可以保证我们用更简洁清楚和更少的代码来完成我们的工作。

如果博客对您有帮助,不妨请我喝杯咖啡...