Kotlin笔记 Class和继承

Class定义

定义class

class Invoice {
}

如果没有body,括号可以省略

class Empty

构造函数

类有primary constructorsecondary constructorprimary 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.ObjectAny只包含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.f() // call to A.f()
        super.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
}

你可能感兴趣的:(Kotlin笔记 Class和继承)