Kotlin 实战笔记
接口
使用 interface
关键字来声明一个接口。可以包含抽象方法和非抽象方法(带默认实现的方法):
1 | interface Clickable { |
实现类可以使用类似 Java 的 super
关键字来调用接口的非抽象方法;但是,如果实现的多个接口中有相同名字的非抽象方法,此时实现类必须重写该方法,并且对它们的调用也有所不同:
1 | interface Focusable { |
类
final、open
Kotlin 中默认情况下类、方法、属性都是是 final
和 public
的,即不可被继承(不可重写),需要显式的用 open
关键字修饰才可被继承(可重写):
1 | open class Button : Clickable, Focusable { |
abstract
使用 abstract
关键字来声明抽象类,抽象方法默认是 open
的,而非抽象方法并不是默认为 open
的:
1 | abstract class Animated { |
内部类、嵌套类
嵌套类类似于 Java 中的静态内部类,不持有外部类的引用;内部类类似于 Java 中的普通内部类,持有外部类引用:
1 | class Outer { |
初始化类
constructor
关键字用来构造方法的声明;init
关键字用来引入初始化语句块,类似于 Java 构造方法中的初始化工作。
在声明类时用括号包裹起来的就是主构造方法,它的目的有两个:表明构造方法的参数、声明属性并将参数赋值给属性。
1 | // (val nickname: String) 就是主构造方法 |
上面两个 User 的声明是等价的。构造方法参数可以和普通方法参数一样使用默认值。
如果想要确保类不被其他代码实例化,需要使用 private
关键字修饰构造方法:
1 | class Secretive private constructor() {} |
构造方法
除了主构造方法外还可以声明多个从构造方法:
1 | class View { |
数据类
使用 data
关键字可以声明类为数据类。
1 | data class Client(val name: String, val postalCode: Int) |
数据类自动生成了一些常用的方法:
- equals:用来比较实例
- hashCode:用来作为例如 HashMap 这种基于哈希容器的键
- toString:用来为类生成按声明顺序排列的所有字段的字符串表达形式
- copy:用来创建对象副本
object 关键字
object
关键字定义一个类并同时创建一个实例(对象),使用场景:
- 对象声明:是定义单例的一种方式
- 伴生对象:可以持有工厂方法和其他与这个类相关
- 对象表达式:用来替代 Java 的匿名内部类
对象声明:单例
一个对象声明可以包含属性、方法、初始化语句块,但是不允许声明构造方法(包括主构造方法和从构造方法),同时也可以继承类和接口。
1 | // object 将类的声明和对象的创建放在了一起 |
对象声明也可以在类中,这样的对象同样只有一个单一实例:
1 | class Test { |
看看编译后的 Java 代码:
1 | public static final class Singleton { |
伴生对象
伴生对象就是在对象声明的基础上使用了 companion
关键字,但是伴生对象必须声明在类里面。
1 | class Factory { |
伴生对象和对象声明很像,但是它们编译后的 Java 代码却有区别:
1 | public final class Factory { |
对象表达式:匿名对象
匿名对象替代了 Java 中的匿名内部类的用法:
1 | // Java |