基础语法
构建一个简单的 Person 类,示例如下:
calss Person(val name: String, var isMarried: Boolean)
此时 Person 类有一个可读属性 name 和一个可写属性 isMarried,在声明属性的时候会自动为其创建访问器(只读属性有一个 getter,可写属性有 getter 和 setter)
当然也可以自定义访问器,示例如下:
calss Rectangle(val height: Int, val width: Int) {
val isSquare: Boolean
get() {
return height == width
}
}
也可以修改访问器的可见性,示例如下:
class LengthCounter{
//此时不能在类的外部修改这个属性
var counter: Int = 0
private set
fun addWord(word: String){
counter += word.length
}
}
构造函数
主构造方法
- 定义一个包含主构造方法的类的示例如下:
calss Person(val name: String, var isMarried: Boolean)
- 括号中的即为主构造方法,当然也可以为参数设置默认值,示例如下;
calss Person(val name: String, var isMarried: Boolean = false)
- 也可以把主构造方法设置为私有,示例如下:
calss Secretive private constructor() {
}
- 主构造方法中不能包含代码语句,因此初始化代码可以放到 init 初始化块中,示例如下:
calss Person(var name: String?){
init{
//初始化块中可以使用主构造方法中的参数(name)
print("my name is $name")
}
}
注:如果同时包含 init 初始化块和从构造函数,init 初始化块会优于从构造函数执行
从构造方法
calss View{
constructor(ctx: Context){
...}
constructor(ctx: Context, attr: AttributeSet){
...}
}
数据类
通过为类添加 data 修饰符可以将其声明为数据类,数据类会自动为我们重写以下所有标准 Java 方法:
- equals 用来比较实例
- hashCode 用来作为例如 HashMap 这种基于哈希容器的键
- toString 用来为类生成按声明顺序排列的所有字段的字符串表达形式
构造数据类的示例如下:
data calss Person(val name: String, var isMarried: Boolean)
类委托
通过使用 by 关键字可以实现类委托机制:创建一个新类,实现与原始类一样的接口并将原来的类的实例作为一个字段保存,与原始类拥有相同行为的方法不用被修改,只需要转发到原始类的实例。示例如下:
不使用委托机制时,构建一个 Collection 的接口的装饰器,不修改任何行为:
class DelegatingCollection<T>: Collection<T>{
private val innerList = arrayListOf<T>()
override val size: Int get() = innerList.size
override fun empty(): Boolean = innerList.empty()
override fun contains(element: T): Boolean = innerList.contains(element)
override fun iterator(): Iterator<T> = innerList.iterator()
override fun containsAll(elements: Collection<T>): Boolean = innerList.containsAll(elements)
}
在使用类委托机制时其代码如下:
class DelegatingCollection<T>(
innerList: Collection<T> = ArrayList<T>()
): Collection<T> by innerList {
}
创建实例
Kotlin 中调用构造方法不需要 new 关键字,创建一个类的示例如下:
calss Person(val name: String, var isMarried: Boolean)
val person = Person("Bob", true)
类中的访问修饰符
修饰符 | 相关成员 | 评注 |
---|---|---|
final(默认) | 不能被重写 | 类中成员默认使用 |
open | 可以被重写 | 需要明确的表明 |
abstract | 必须被重写 | 只能在抽象类中使用;抽象成员不能持有 |
override | 重写父类或接口中的成员 | 如果没有使用 final 表明,重写的成员默认是开放的 |
注:当一个类允许被继承,或者一个方法允许被重写时都需要显示地用 open 修饰符修饰。
可见性修饰符
修饰符 | 类成员 | 顶层声明 |
---|---|---|
public(默认) | 所有地方可见 | 所有地方可见 |
internal | 模块中可见 | 模块中可见 |
protected | 子类中可见 | —— |
private | 类中可见 | 文件中可见 |
注:internal 修饰符在字节码中会变成 public。
内部类
类 A 在另一个类 B 中声明 | 在 Java 中 | 在 Kotlin 中 |
---|---|---|
嵌套类(不储存外部类的引用) | static class A | class A |
内部类(储存外部类的引用) | class A | inner class A |
Kotlin 中内部类引用外部类实例需要使用 this@Outer,示例如下:
class Outer{
inner class Inner{
fun getOuterReference(): Outer = this@Outer
}
}
枚举类
- 声明一个简单的枚举类:
enum class Color {
RED, GREEN, BLUE
}
- 声明一个带属性值的枚举类:
enum class Color(val r: Int, val g: Int, val b: Int) {
RED(255, 0, 0), GREEN(0, 255, 0), BLUE(0, 0, 255);
//定义一个方法
fun rgb() = (r * 256 + g) * 256 + b
}
- 使用 when 来选择正确的枚举值
fun getColor(color: Color) =
when (color) {
Color.RED -> "Richard"
Color.GREEN -> "Gave"
Color.BLUE -> "Battle"
}
注:when 是一个有返回值的表达式。
抽象类
声明一个抽象类的示例如下:
abstract class Animated{
//抽象函数,必须被子类重写
abstract fun animate()
//用 open 修饰可以被重写
open fun stopAnimating(){
}
//没有被 open 修饰,不可用于重写
fun animateTwice(){
}
}
单例类
使用 object 关键字可以在定义一个类的同事创建一个实例,示例如下:
object Single{
...
}