美文网首页Kotlin编程
Kotlin笔记 Class和继承

Kotlin笔记 Class和继承

作者: yangweigbh | 来源:发表于2017-01-14 17:24 被阅读1774次

    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<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
    }
    

    相关文章

      网友评论

        本文标题:Kotlin笔记 Class和继承

        本文链接:https://www.haomeiwen.com/subject/uauebttx.html