Class定义
定义class
class Invoice {
}
如果没有body,括号可以省略
class Empty
构造函数
类有primary constructor
和secondary constructor
,primary constructor
定义在类的头部,
class Person constructor(firstName: String) {
}
如果构造函数没有修饰符,可以把constructor
修饰符省略
class Person(firstName: String) {
}
primary constructor
的逻辑放在init block里
class Customer(name: String) {
init {
logger.info("Customer initialized with value ${name}")
}
}
init block和类变量初始化可以使用primary constructor
的参数
也可以在primary constructor
里直接声明类变量
class Person(val firstName: String, val lastName: String, var age: Int) {
// ...
}
第二构造函数
第二构造函数在函数里用constructor
关键字声明
class Person {
constructor(parent: Person) {
parent.children.add(this)
}
}
如果类有primary constructor
那么第二构造函数需要使用this
直接或者间接的调用primary constructor
class Person(val name: String) {
constructor(name: String, parent: Person) : this(name) {
parent.children.add(this)
}
}
如果非抽象类没有定义构造函数,那么编译器会自动添加无参public
构造函数。
创建实例
不需要用new关键字
val invoice = Invoice()
val customer = Customer("Joe Smith")
类的成员
类可以包含
- 构造函数和init block
- 函数
- 变量
- Nested and inner Classes
- Object声明(单例)
继承
Any
是任何类的基类。Any
不是java.lang.Object
。Any
只包含equals()
, hashCode()
, toString()
函数。
继承其他类时,在类定义头最后加上:父类
open class Base(p: Int)
class Derived(p: Int) : Base(p)
如果类有primary constructor
,那么在它之后初始化父类,如上,如果没有primary constructor
,则在secondary constructor
里通过super
关键字初始化父类
class MyView : View {
constructor(ctx: Context) : super(ctx)
constructor(ctx: Context, attrs: AttributeSet) : super(ctx, attrs)
}
open
关键字与Java里final
相反,它允许类被继承,Kotlin里类都是默认不允许继承的。
只有open的方法,子类才能重写,重写时必须加上override
open class Base {
open fun v() {}
fun nv() {}
}
class Derived() : Base() {
override fun v() {}
}
final 类里open方法是非法的
override
的方法默认是open
的,如果要改写open
,需要加上final
关键字
open class AnotherDerived() : Base() {
final override fun v() {}
}
如果多个父类里有同名的成员,子类需要通过overide这个同名成员
open class A {
open fun f() { print("A") }
fun a() { print("a") }
}
interface B {
fun f() { print("B") } // interface members are 'open' by default
fun b() { print("b") }
}
class C() : A(), B {
// The compiler requires f() to be overridden:
override fun f() {
super<A>.f() // call to A.f()
super<B>.f() // call to B.f()
}
}
抽象类
可以用abstract
修饰类和类方法,抽象方法没有实现
Companion Objects
Kotlin中的类没有静态方法,用包级函数代替
companian objects
可以定义出类似静态函数的效果
class MyClass {
companion object Factory {
fun create(): MyClass = MyClass()
}
}
val instance = MyClass.create()
Sealed Classes
定义为sealed class
的子类只能声明在sealed class
的body里,sealed class
的子类的子类可以声明在body外面
sealed class Expr {
class Const(val number: Double) : Expr()
class Sum(val e1: Expr, val e2: Expr) : Expr()
object NotANumber : Expr()
}
使用sealed class
的好处是,在when
里不用再使用else
fun eval(expr: Expr): Double = when(expr) {
is Expr.Const -> expr.number
is Expr.Sum -> eval(expr.e1) + eval(expr.e2)
Expr.NotANumber -> Double.NaN
// the `else` clause is not required because we've covered all the cases
}