Kotlin笔记(四)——类和类的构造器

来源:互联网 发布:中国网络电视在线直播 编辑:程序博客网 时间:2024/06/01 09:51

从这篇文章开始,我们进入Kotlin面向对象编程的世界,这部分的内容相对较多,也是十分重要的,我尽可能将我所学到的介绍给大家。


可见性修饰符

在开始介绍类之前,先来简单说明一下Kotlin的可见性修饰符。Kotlin的可见性修饰符有四种:public,protected,private和internal,如果不加任何修饰符,默认是public。它们可以用于修饰顶级元素(函数和类等全局元素),也可以用于修饰类中的成员变量和方法,而后者使用更为广泛。


当用于修饰类中的成员时,有以下规则:

private:仅在类内可见;

protected:类内和子类中可见;

internal:模块内可见,一个模块是一个Kotlin编译文件的集合,而不是一个包

public:随处可见


类的定义

了解了可见性修饰符,我们看一下类的定义,类使用关键字class定义

class AClass {}

这样我们就定义了一个名称为AClass的类。该类有一个无参构造器,不需要显式定义。


类的构造器

类需要通过构造器,才能够生成对应的对象。Kotlin中构造器分为两种:首要构造器和次要构造器。首要构造器只有一个,而次要构造器可以有多个,但是次要构造器都要使用首要构造器完成构造后,添加自己的构造过程。下面我们还是采用逐步演化的方式,讲解类的构造器。我们的示例是一个Person类,有两个成员变量姓名(name)和年龄(age),完整的定义如下

class Person1 public constructor(name: String="Monkey", age: Int=12) {    init {        println("姓名:$name")        println("年龄:$age")    }    constructor(name: String) : this(name, 15) { }}

我们定义一个Person1类,紧跟其后的是首要构造器,该构造器的可见性为public,首要构造器有两个参数,姓名和年龄,且具有默认值。类内部有一个init关键字开头的代码块,这称之为初始化块,由于Kotlin的首要构造器不存在函数体,可以在init代码块中加入一些初始化逻辑。类的内部还有一个constructor函数,这就是次要构造器,其后通过this调用了首要构造器,次要构造器函数体内为空。


我们定义几个对象,看看init块中的打印

//使用有默认参数的构造函数var person1 = Person1()//使用完整的首要构造函数person1 = Person1("Tom", 13)//使用次要构造函数person1 = Person1("Jim")

我们定义了三个对象,由于构造对象时必然会调用init代码块,所以我们运行后看到结果如下


姓名:Monkey
年龄:12
姓名:Tom
年龄:13
姓名:Jim
年龄:15


前两个不再过多解释,主要看一下第三个,我们使用了带有一个参数的构造器,那么到底使用的是次要构造器还是首要构造器使用了age的默认参数呢?从结果很容易发现,我们使用的是次要构造器,也就是Kotlin会找到最匹配的构造器使用。


上面的定义太复杂了,我们开始做一些简化。首先,首要构造器的可见性默认为public,所以,如果可见性为public,我们可以省略可见性描述符。由于可见性描述符被省略了,constructor也可以省略,一起摘掉吧。由于次要构造器没有函数体,大括号也可以去掉。

class Person2(name: String="Monkey", age: Int=12) {    init {        println("Person2 姓名:$name")        println("Person2 年龄:$age")        //试图修改参数值        //name = "Tom"    }    constructor(name: String) : this(name, 15)}

当然,如果不需要init代码块和参数默认值,也可以去掉。总之,上面的例子基本上可以算作最简化的类定义了。


最后强调一点,构造器参数默认是只读的,不可以对参数进行修改,否则将无法通过编译,例如尝试修改常量参数,会编译报错

name = “Tom”


如果需要修改,可以在构造器参数前加上修饰符var

class Person3(var name: String="Monkey", age: Int=12) {    init {        println("Person3 姓名:$name")        println("Person3 年龄:$age")        name = "Tom"    }    constructor(name: String) : this(name, 15)}

但此时name实际上已经不再是构造器参数了,它已经成为了一个类的属性,而age还是一个构造器参数。关于类的属性,后续的文章会详细介绍,现在只需要记住类的属性可以通过var和val定义其读写性。


下面给出一些Kotlin类的概述,后续文章会有更详细的说明:

1.类可以继承多个类,可以实现接口;

2.可以定义抽象类;

3.可以定义数据类;

4.可以对已有类进行扩展;

5.类的内部可以包含:

——构造器和初始化块

——方法

——属性

——内部类

——匿名对象