从这篇文章开始,我们进入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) { }
}
我们定义几个对象,看看init块中的打印
//使用有默认参数的构造函数
var person1 = Person1()
//使用完整的首要构造函数
person1 = Person1("Tom", 13)
//使用次要构造函数
person1 = Person1("Jim")
姓名: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.类的内部可以包含:
——构造器和初始化块
——方法
——属性
——内部类
——匿名对象