美文网首页
Android:Kotlin详细入门学习指南-类和对象-基础语法

Android:Kotlin详细入门学习指南-类和对象-基础语法

作者: 拖鞋王子猪 | 来源:发表于2021-01-25 15:12 被阅读0次

    本人也是在初学Kotlin,如有错误,请帮忙指出,持续更新

    Android:Kotlin详细入门学习指南-类和对象-基础语法(四)

    建议先看看前面的文章
    Android:Kotlin详细入门学习指南-基础语法(一)

    Android:Kotlin详细入门学习指南-基本类型-基础语法(二)

    Android:Kotlin详细入门学习指南-包-控制流-返回与跳转-基础语法(三)

    这篇文章分享的内容比较多,建议先关注收藏,再查看,以免迷路

    类和对象

    • 类和继承
    • 属性和字段
    • 接口
    • 可见性修饰词
    • 扩展
    • 数据对象
    • 泛型
    • 嵌套类
    • 枚举类
    • 对象表达式和声明
    • 委派模式
    • 委派属性
    类和继承

    在 Kotlin 中类用 class 声明:

    class Invoice { }
    

    类的声明包含类名,类头(指定类型参数,主构造函数等等),以及类主体,用大括 号包裹。类头和类体是可选的;如果没有类体可以省略大括号。

    构造函数

    Kotlin的构造函数和java的还是有点区别
    在 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 customerKry = name.toUpperCase() 
    }
    

    声明属性并在主构造函数中初始化,在 Kotlin 中有更简单的语法

    class Person(val firstName: String, val lastName: String, var age : Int) { }
    

    在主构造函数中的属性可以是可变的( var )或只读的( val )。 如果构造函数有注解或可见性声明,则 constructor 关键字是不可少的

    二级构造函数

    类似java的重载
    类也可以有二级构造函数,需要加前缀 constructor :

    class Person { 
        constructor(parent: Person) { 
            parent.children.add(this) 
        } 
    }
    

    如果类有主构造函数,每个二级构造函数都要,或直接或间接通过另一个二级构造 函数代理主构造函数。在同一个类中代理另一个构造函数使用 this 关键字:

    class Person(val name: String) { 
        constructor (name: String, paret: Person) : this(name) { 
            parent.children.add(this) 
        } 
    }
    

    如果一个非抽象类没有声明构造函数(主构造函数或二级构造函数),它会产生一个 没有参数的构造函数。该构造函数的可见性是 public 。如果你不想你的类有公共的 构造函数,你就得声明一个拥有非默认可见性的空主构造函数:

    class DontCreateMe private constructor () { }
    

    注意:在 JVM 虚拟机中,如果主构造函数的所有参数都有默认值,编译器会 生成一个附加的无参的构造函数,这个构造函数会直接使用默认值。这使得 Kotlin 可以更简单的使用像 Jackson 或者 JPA 这样使用无参构造函数来创建类 实例的库。

    创建类的实例
    val invoice = Invoice() 
    val customer = Customer("Joe Smith")
    

    注意 Kotlin 没有 new 关键字。
    内部类要使用inner关键字。

    类成员

    类可以包含:

    • 构造函数和初始化代码块
    • 函数
    • 属性
    • 内部类
    • 对象声明
    继承

    Kotlin 中所有的类都有共同的父类 Any ,java是Obejct,它是一个没有父类声明的类的默认父 类:
    Any 不是 java.lang.Object ;事实上它除了 equals() , hashCode() 以 及 toString() 外没有任何成员了。
    声明一个明确的父类,需要在类头后加冒号再加父类

    open class Base(p: Int) 
    class Derived(p: Int) : Base(p)
    

    普通的类如果需要被继承就需要有open关键字
    open 注解与java中的 final 相反:它允许别的类继承这个类。默认情形下,kotlin 中所有的类都是 final

    复写方法
    open class Base { 
        open fun v() {} 
        fun nv() {} }
    class Derived() : Base() { 
        override fun v() {} 
    }
    

    对于 Derived.v() 来说 override 注解是必须的。如果没有加的话,编译器会 提示。如果没有 open 注解,像 Base.nv() ,在子类中声明一个同样的函数是不 合法的,要么加 override 要么不要复写。在 final 类(就是没有open注解的类) 中, open 类型的成员是不允许的。
    普通方法标记open,可被重写

    复写属性

    复写属性与复写方法类似,在一个父类上声明的属性在子类上被重新声明,必须添 加 override ,并且它们必须具有兼容的类型。每个被声明的属性都可以被一个带 有初始化器的属性或带有getter方法的属性覆盖

    复写规则

    在 kotlin 中,实现继承通常遵循如下规则:如果一个类从它的直接父类继承了同一 个成员的多个实现,那么它必须复写这个成员并且提供自己的实现(或许只是直接用 了继承来的实现)。为表示使用父类中提供的方法我们用 super<Base> 表示:

    open class A { 
        open fun f () { 
            print("A") 
        } 
        fun a() { 
            print("a") 
        } 
    }
    interface B { 
        fun f() { 
            print("B") 
    } // 接口的成员变量默认是 open 的 
    fun b() { 
        print("b") 
        } 
    }
    class C() : A() , B { 
    // 编译器会要求复写f() 
        override fun f() { 
            super<A>.f() // 调用 A.f() 
            super<B>.f() // 调用 B.f() 
        } 
    }
    

    可以同时从 A 和 B 中继承方法,而且 C 继承 a() 或 b() 的实现没有任何问题,因为 它们都只有一个实现。但是 f() 有俩个实现,因此我们在 C 中必须复写 f() 并且提供 自己的实现来消除歧义。
    这次就先分享到这里,下次再继续分享。

    本人也是在初学Kotlin,如有错误,请帮忙指出,持续更新

    相关文章

      网友评论

          本文标题:Android:Kotlin详细入门学习指南-类和对象-基础语法

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