1. 类的声明
Kotlin 中使用关键字 class 声明类,这点与 Java 一样:
package cn.zzw.messenger.hellokotlin
/**
*@author 鹭岛猥琐男
*@create 2019/9/24 21:30
*/
class UserInfo {
}
类声明由类名、类头(指定其类型参数、主构造函数等)以及由花括号包围的类体构成。
如果一个类没有类体,花括号可以省略:
class UserInfo
2. 构造函数
一个类可以有一个主构造函数以及一个或者多个次构造函数。主构造函数是类头的一部分:它跟类名后。
class UserInfo(name: String, age: Int) {
}
2.1 主构造函数
主构造函数不能包含任何的代码。初始化的代码可以放到以 init 关键字作为前缀的初始化块中:
class UserInfo(name: String, age: Int) {
init {
var info = "My Name is " + name + " ,My age is " + age;
Log.e("zzw", "UserInfo:" + info)
}
}
与普通属性一样,主构造函数中声明的属性可以是可变的(var)或只读的(val):
class UserInfo(var name: String, val age: Int) {
}
如果没有为其显式提供Primary Constructor,Kotlin编译器会默认为其生成一个无参主构造 。
class CountryInfo {
}
2.2 次构造函数
次构造函数是定义在类体中,次构造函数可以有多个,主构造函数只有一个:
/**
*@author 鹭岛猥琐男
*@create 2019/9/24 21:58
*/
class User {
private val username: String
private var age: Int
constructor(username: String, age: Int) {
this.username = username
this.age = age
}
}
3. 创建类的实例
var userInfo = UserInfo("zuowei.zhang", 11);
var person= Person()
注意:Kotlin 中并没有 new 关键字。
4. 继承
在 Kotlin 中所有类都有一个共同的超类 Any,对于没有超类声明的类是默认超类:
class Example // 从 Any 隐式继承
Any 有三个方法:equals()、 hashCode() 与 toString(),所有的 Kotlin 类都定义了这些方法。
在 Kotlin 中,所有的类在默认情况下都是无法被继承的,也就是说,所有类在默认情况下都是 final 的。在 Kotlin 中,有一个关键字 open,只有被 open 修饰的类才可以被继承:
Parent 类:
package cn.zzw.messenger.hellokotlin
/**
*@author 鹭岛猥琐男
*@create 2019/9/25 20:09
*/
open class Parent(name: String, age: Int) {
}
Child 类:
package cn.zzw.messenger.hellokotlin
/**
*@author 鹭岛猥琐男
*@create 2019/9/25 20:10
*/
class Child(name: String, age: Int) : Parent(name, age) {
}
5. 类的方法重写
在 Kotlin 中,类的方法是不能被重写的,如果需要重写需要在方法前面加上关键字 open:
open class Parent(name: String, age: Int) {
fun eat(){
}
open fun drink(){
}
}
在类 Parent 中,方法 drink() 加了 open 关键字,在类 Child 中只有 drink() 可以被重写:
class Child(name: String, age: Int) : Parent(name, age) {
override fun drink() {
super.drink()
}
}
6. 类的属性
6.1 属性的声明
声明一个属性的完整语法是:
var <propertyName>[: <PropertyType>] [= <property_initializer>]
[<getter>]
[<setter>]
set和get可写也可不写, 不写的话会有默认的实现。val 修饰的属性是没有 set 方法的,也不允许重写 set 方法。
class Person {
var name: String = "zzw"
set(value: String) {
field = value
}
get() = field.toUpperCase()
}
6.2 属性的覆盖
属性覆盖与方法覆盖类似:在超类中声明然后在派生类中重新声明的属性必须以 override 开头,并且它们必须具有兼容的类型。
a. val属性是可以被val的属性所 override 的;
b. var属性是可以被val属性 override 的;
c. val属性是不能被var属性所 override 的。
d. 本质上 val 相当于 get 方法,var 相当于 set 与 get 方法
open class Parent(name: String, age: Int) {
open val school: String = "集美中心"
fun eat(){
}
open fun drink(){
}
}
class Child(name: String, age: Int) : Parent(name, age) {
override val school: String
get() = super.school
override fun drink() {
super.drink()
}
}
7. 抽象类
类以及其中的某些成员可以声明为 abstract。 抽象成员在本类中可以不用实现。 需要注意的是,不需要用 open 标注一个抽象类或者函数。
/**
*@author 鹭岛猥琐男
*@create 2019/9/25 21:39
*/
abstract class Presenter {
abstract fun onStart()
}
8. 接口
8.1 接口的定义
Kotlin 的接口可以既包含抽象方法的声明也包含实现。与抽象类不同的是,接口无法保存状态。它可以有属性但必须声明为抽象或提供访问器实现。
使用关键字 interface 来定义接口:
/**
*@author 鹭岛猥琐男
*@create 2019/9/28 9:42
*/
interface MyInterface {
fun bar()
}
8.2 接口中的属性
可以在接口中定义属性。在接口中声明的属性要么是抽象的,要么提供访问器的实现。
package cn.zzw.messenger.hellokotlin
/**
*@author 鹭岛猥琐男
*@create 2019/9/28 9:42
*/
interface MyInterface {
val prop:Int
fun bar()
fun foo() {
// 可选的方法体
}
}
package cn.zzw.messenger.hellokotlin
import android.util.Log
/**
*@author 鹭岛猥琐男
*@create 2019/10/15 20:47
*/
class ChildMyInterface : MyInterface {
override val prop = 29
override fun bar() {
Log.e("zzw", "ChildMyInterface: fun bar()");
}
}
9. 数据类
创建一些只保存数据的类:
/**
*@author 鹭岛猥琐男
*@create 2019/10/15 21:02
*/
data class Student(var name:String, var age:Int)
调用:
var student = Student("zuowei.zhang", 110);
student.age = 999;
编译器会为数据类(data class)自动生成以下函数:
equals()/hashCode()
toString() 默认输出"User(name=John, age=42)"
componentN() 按声明顺序对应于所有属性
copy()
参考: