Kotlin类与继承
类定义 类声明由类名、类首部(指定类型参数,主构造器等)、类正文(用花括号包围)。类首部和正文都是可选的。因此最简单的类定义为: class Empty // Implicitly inherits from Any 类似所有Java类都继承类Object,所有Kotlin类都继承类Any,但Any不是与特定平台(例如JVM)相关的,它不是一个java.lang.Object,这表明当Kotlin与Java代码进行互操作时,为了使用Object的成员方法,Kotlin提供了扩展函数。 例如为了调用Object的wait()/notify()方法,可以将一个kotlin对象foo转型为Object: (foo as java.lang.Object).wait() 为了获取一个kotlin对象的Java类,Kotlin1.1之后可以使用class引用的java扩展属性,也可以直接使用扩展属性javaClass: val fooClass = foo::class.java // class reference val fooClass = foo.javaClass // extension property: javaClass 与Java代码进行互操作,Kotlin在语言层面上是这样设计的,但在编译为Java字节码以及JVM运行时中,每个类总是默认继承了Object。 构造器 Kotlin的构造器分为主构造器(primary constructor)和次要构造器(secondary constructors)。两者都是可选的,即可以不用明确定义任何构造器,这时如果该类不是抽象类,就采用默认生成的无参主构造器。主构造器只能有一个,次要构造器可以有多个,次要构造器必须代理到主构造器,可以是直接的代理或使用其它次要构造器间接代理。造器的可见性默认是public的。 这里讨论下主构造器,先了解下Java对象的初始化,大致说了Java对象初始化机制有三种:实例初始化器(初始化块)、实例变量初始化器、构造器。初始化块和实例变量初始化器可以认为是实例初始化器的两种不同形式,实例变量初始化器只不过定义了实例变量并使用表达式而非块进行了初始化。在对象初始化时,由于存在继承层次结构,每一层级类都需要进行初始化,一个对象从自身开始向上到父类,到父类的父类等等,直到Object类,完成整个类层次的初始化。所以该对象的构造器必须直接或间接地调用父类构造器,这也说明了为什么构造器不属于Java类成员,它不会被子类继承,不然会造成初始化的死循环。构造器是初始化的入口,但不是初始化的全部,并且为了保证初始化过程的顺序,编译器会为每个构造器生成一个<init>方法,包含以下代码: 对另一个构造函数的调用(为了直接或间接调用父类构造器) 初始化器(包括变量初始器器和块初始化器,为了保证初始化器仅运行一次,如果第1步调用是本地另一个构造函数,那么便不需要 初始化器的代码) 构造函数正文 在Kotlin中,初始化块使用init关键字声明: init { print("This is a intializer block.") } 如果一个Kotlin类未继承其它另外定义的类,那么它默认继承类Any, 如下所示: 未定义主构造器 未定义次要构造器:编译器会为其生成一个无参主构造器 定义了次要构造器:那么它将仅有次要构造器,不会自动生成无参构造器 class Car { // ... constructor(type: String, name: String) { // ... } } 定义了主构造器,并且定义了次要构造器 class Car(type: String, name: String) { // ....