一、类与对象
下面的将示范如何创建一个Kotlin类:
1 2 3 4 5 6 7 8
| class Person { var name = "" var age = 0
fun show() { println(name + "," + age + "岁") } }
|
然后将这个类进行实例化,获得一个对象
1 2 3 4 5 6
| fun main() { val p = Person() p.name = "田所浩二" p.age = 24 p.show() }
|
二、类的继承与构造函数
首先,在Kotlin中,所有非抽象类默认都是不可继承的,就像Java中的final声明的类,要使得类能悲继承,需要open关键字。
1 2 3
| open class Person { ... }
|
然后我们让Student类继承Person类,使用一个冒号,注意被继承类名后面的括号:
1 2 3 4
| class Student : Person() { var id = "" var grade = 0 }
|
另外是关于构造函数的部分。Kotlin将构造函数分成了两种:主构造函数和次构造函数。
1.主构造函数
主构造函数是每个类默认都会有的一个不带参数的构造函数,我们也可以给它指定参数。主构造函数没有函数体,直接定义在类名后面:
1 2 3 4 5 6
| class Student(val id: String, val grade: Int): Person() { }
val student = Student("1145141919810", 5)
|
主构造函数没有函数体,如果想在其中编写逻辑,可以使用init结构体:
1 2 3 4 5 6
| class Student(val id: String, val grade: Int): Person() { init { println("id is " + id) println("grade is " + grade) } }
|
根据继承的规定,子类的构造函数必须调用父类的构造函数,我们就需要在括号中填入父类构造函数的参数:
1 2 3 4 5 6 7 8 9 10 11 12 13
| open class Person(val name: String, val age: Int) { ... }
class Student(val id: String, val grade: Int, name: String, age: Int): Person(name, age) { init { println("id is " + id) println("grade is " + grade) } }
|
2.次构造函数
一个类能有多个次构造函数,如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
| class Student(val id: String, val grade: Int, name: String, age: Int): Person(name, age) { constructor(name: String, age: Int): this("", 0, name, age) {
}
constructor(): this("", 0) {
} }
val st1 = Student() val st2 = Student("我修院卓", 23) val st3 = Student("1145141919810", 5, "田所浩二", 24)
|
如果类中没有主构造函数,只有次构造函数该怎么继承?代码如下:
1 2 3 4
| class Student : Person { constructor(name: String, age: Int) : super(name, age) {} }
|
三、接口
不同于C++的多继承,Java和Kotlin都是单继承结构的语言,最多只允许继承一个父类,但可以实现任意个接口 接口中定义的函数可以不实现,也可以定义默认的实现。Kotlin只会强制要求实现没有默认实现的函数。 接口定义方法如下:
1 2 3 4 5 6
| interface Study { fun readBooks() fun doHomework() { println("doing homework") } }
|
让Student类实现这个接口, 和继承的写法一样,然后再使用override关键字重载接口定义的函数:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
| class Student(name: String, age: Int) : Person(name, age), Study { override fun readBooks() { println(name + " is reading.") } override fun doHomework() { println(name + " is doing homework") } }
fun main() { val stu = Student("田所浩二", 24) doStudy(stu) }
fun doStudy(stu: Study) { stu.readBooks() stu.doHomework() }
|
四、可见性修饰符
Java中有四种修饰符:public、private、protected、default,默认是default。
Kotlin也有四种:public、private、protected、internal, 默认是public。
| public |
所有类可见 |
所有类可见(默认) |
| private |
当前类可见 |
当前类可见 |
| protected |
当前类、子类、同一煲路径下的类可见 |
当前类,子类可见 |
| default |
同一包路径下的类可见(默认) |
无 |
| internal |
无 |
同一模块中的类可见 |
五、数据类
在一个规范的系统架构中,数据类用于将服务器端或数据库中的数据映射到内存中,为编程逻辑提供数据模型的支持。
在Java中数据类通常需要重写equals()、hashCode()、toString()这几个方法,而Kotlin则只需要一个data关键字,这些方法便会自动生成:
1
| data class Cellphone(val brand: String, val price: Double)
|
当一个类内部没有任何代码,便可以将大括号省略。 下面测试一下这个数据类:
1 2 3 4 5 6
| fun main() { val cellphone1 = Cellphone("Samsung", 1299.99) val cellphone2 = Cellphone("Samsung", 1299.99) println(cellphone1) println("cellphone1 == cellphone2 ? " + (cellphone1 == cellphone2)) }
|
运行结果如下:
Cellphone(brand=Samsung, price=1299.99)
cellphone1 == cellphone2 ? true
六、单例类
使用单例可以避免创建重复的对象,保证一个类最多拥有一个实例。
在Java中创建单例类需要以下几个步骤:
- 将类的构造函数私有化
- 向外部提供一个
getInstance()的静态方法用于获取该类实例
- 在
getInstance()中,判断如果当前缓存的实例为null,就创建一个新的实例并将其缓存,否则直接返回缓存的实例即可。
在Kotlin中,只需要将class关键字改成object关键字即可声明单例类:
1 2 3 4 5 6 7 8
| object Singleton { fun test() { println("test is called") } }
Singleton.test()
|
看上去就像是调用了静态方法,其实是Kotlin在背后自动创建了一个类的实例,并且保证全局只有一个该类的实例。