本文是对kotlin的官方文档进行翻译,供自己学习方便,英语比较好的朋友可以直接看官方文档。官方文档
一、类
在kotlin中和在java中一样,类的声明使用关键字class
class Invoice {
}
类的声明由类名,类头(指定参数类型,主构造函数等)和类体组成,由大括号括起来。 类头和类体都是可选的; 如果类没有类体,可以省略大括号。
class Empty
kotlin中的一个类可以有一个主要的构造函数和一个或多个辅助构造函数。主构造函数是类头的一部分:它在类名后面(和可选的类型参数)。
class Person constructor(firstName: String) {
}
如果主构造函数没有任何的注解或者可见的修饰符,那么constructor可以省略。
class Person(firstName: String) {
}
主构造函数不能包含任何代码。初始化代码可以放在初始化程序块中,前缀为init关键字:
class Customer(name: String) {
init {
logger.info("Customer initialized with value ${name}")
}
}
请注意,主构造函数的参数可以在初始化程序块中使用。它们也可以用在类体的属性初始化声明中:
class Customer(name: String) {
val customerKey = name.toUpperCase()
}
实际上,为了声明属性并初始化主构造函数中的参数,Kotlin有一个简洁的语法:
class Person(val firstName: String, val lastName: String, var age: Int) {
// ...
}
与常规属性一样,在主构造函数中声明的属性可以是可变的(var)或只读(val)。
如果构造函数具有注释或可见性修饰符,那么构造函数关键字constructor是必需的,修饰符就在它之前:
class Customer public @Inject constructor(name: String) { ... }
三、辅助构造函数
一个类可以声明辅助构造函数,辅助构造函数要用constructor作为前缀。
class Person {
constructor(parent: Person) {
parent.children.add(this)
}
}
如果类具有主构造函数,则每个辅助构造函数需要通过另一个辅助构造函数直接或间接地委派给主构造函数。 使用this关键字对同一类的另一个构造函数进行委派:
class Person(val name: String) {
constructor(name: String, parent: Person) : this(name) {
parent.children.add(this)
}
}
如果一个非抽象类没有声明任何构造函数(主构造函数或辅助构造函数),那么它将生成一个没有参数的主构造函数,构造函数的可见性将是公开的。如果您不希望您的类具有公有构造函数,则需要声明具有非默认可见性的空主构造函数:
class DontCreateMe private constructor () {
}
注意:在JVM中,如果主构造函数的所有参数都具有默认值,编译器将生成一个额外的无参数构造函数,它将使用默认值。 这使得更容易使用Kotlin与诸如Jackson或JPA的库,通过无参数构造函数创建类实例。
class Customer ( val customerName : String = "" )
四、创建实例
要创建一个类的实例,我们调用构造函数,就像它是一个常规函数一样:
val invoice = Invoice()
val customer = Customer("Joe Smith")
五、类成员
一个类包括
1.构造函数和初始化程序块
2.函数
3.属性
4.嵌套和内部类
5.对象声明
六、继承
Kotlin中的所有类都有一个通用的父类Any,(在java中是object)这是一个没有超类声明类的默认父类:
class Example // 隐式继承自Any
Any和Object是不同的,Any除了equals(),hashCode()和toString()之外不具备任何成员。
要声明一个显式的父类,我们将父类放在类头中的冒号后面:
open class Base(p: Int)
class Derived(p: Int) : Base(p)
如果类具有主构造函数,则可以使用主构造函数的参数(并且必须)初始化基类型。
如果类没有主构造函数,则每个辅助构造函数必须使用super关键字初始化基类型,或者委托给另一个构造函数。 请注意,在这种情况下,不同的辅助构造函数可以调用基类型的不同构造函数:
class MyView : View {
constructor(ctx: Context) : super(ctx)
constructor(ctx: Context, attrs: AttributeSet) : super(ctx, attrs)
}
一个类的open注释与Java中的final是相反的,如果一个类用open,那么其他类可以继承自这个类。默认情况下,在kotlin中所有类都是final的。
七、覆盖方法
在kotlin中进行重写要有明确的注释,就是刚才提到的open注释。这一点和java是不相同的。
open class Base {
open fun v() {}
fun nv() {}
}
class Derived() : Base() {
override fun v() {}
}
Derived.v()需要用 override注释,如果缺少,编译器将会提示,如果一个函数没有open注释,比如Base.nv(),在子类中声明相同名字的函数是非法的,不管是否重写。在一个final类中(一个没有open注释的类)open类型的成员是被禁止的。