Kotlin Reference (五) 类的构造函数,类的继承,属性操作

来源:互联网 发布:淘宝女童秋季外套新款 编辑:程序博客网 时间:2024/06/14 01:25

KotLin 相关文档


官方在线Reference
kotlin-docs.pdf
Kotlin for android Developers 中文翻译
Kotlin开发工具集成,相关平台支持指南
Kotlin开源项目与Libraries
Kotlin开源项目、资源、书籍及课程搜索平台
Google’s sample projects written in Kotlin
Kotlin and Android

 

Constructors


下面的代码示例了:

使用constructor,声明构造函数;
init { } 初始化语句块;

//import kotlin.reflect.jvm.internal.impl.javax.inject.Inject/** * desc  : * author: stone * email : aa86799@163.com * time  : 31/05/2017 15 44 */class Person1 constructor(firstName: String) {}//主构造函数可以直接定义在类名后class Person2 constructor(val firstName: String) { }class Person3 constructor(var firstName: String) { }class Person4(firstName: String) { } //如果主构造函数没有任何注解或可见性修饰符,构造函数关键字可以省略class Person5(name: String) {//若主构造函数中,不进行初始化, 可放在init{}中    val name: String    init {        println("initialize")        this.name = name    }}class Person6(name: String) {//主构造函数中的参数初始化,也可以用在成员属性上    val name = String//    val name: String = name}//如果主构造函数前有可见性修饰符或注解,就一定需要加上constructor 关键字class Person7 private/* @Inject*/ constructor(name:String, age: Int)/*当有其它构造函数,依赖主构造函数,形如 constructor(...) : this(...)对于 主构造函数中的参数,如上所说,要么放在init{} ,要么以赋值给成员属性对于 非主构造函数中的参数,在定义属性时,则就需要一个默认值了注意:init{} 要定义在 属性定义后, 否则会访问不到 */class Person8(val name: String) {    var pName: String = name    var pAge: Int = 0 //默认值    init {        pName = name    }    constructor(name: String, age: Int) : this(name) {        pAge = age    }}//其实所有主构造函数中的参数,都会被自动赋上一个默认值, 所以也可以手动指定一个默认值private class Person9(val name: String = "")/*class 中可以有:— Constructors and initializer blocks— Functions— Properties— Nested and Inner Classes— Object Declarations */fun main(args: Array<String>) {    val per9 = Person9("stone")    TT(3)    TT(3, 4)}class TT {//没有在类名后定义主构造函数    constructor(a: Int)    constructor(a: Int, b:Int) : this(a)}

 

inheritance


下面的代码示例了:

使用open, 表示可类被继承,表示函数、属性可被重写;
使用override 表示重写 函数、属性;
kotlin不能声明static的方法和属性;
abstract 声明抽象类与方法

package com.stone.clazzobj.inheritance/** * desc  : 类的继承,方法重写 * author: stone * email : aa86799@163.com * time  : 31/05/2017 16 32 */open class Base1 //使用open后 表示可被继承class Derived1 constructor() : Base1() //继承时,用 : 表示继承关系,且需要表明父类的主构造函数open class Base2(name: String)class Derived2(fName: String) : Base2(fName)//子类没有主构造函数,在内部其它构造函数,使用super 调用父类构造函数open class Base3(name: String)class Derived3 : Base3 {    constructor(name: String) : super(name)}open class Base4 {    open fun v() {}    fun nv() {}}class Derived4() : Base4() {     final override fun v() {}  //final 后  不可被再重写//    override fun nv() {} //非open的fun 不能被重写}open class Foo1 {    open val x: Int get() {return 1 + 3}    /*open var x: Int get() {return x} set(value) {x = value}*/    /*    当声明了属性的get()后,就不会再自动生成对应的set方法了    val 声明的属性 是不会有 set方法的, 因其不可变    属性要被子类重写,也需声明时 加上 open     */}class Bar1 : Foo1() {    override var x: Int = 9}/*如果有多个超类、接口,且它们定义了相同的成员,子类在重写时:使用super<superClass/superInterface> 前缀 来标识 */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()    }}open class AbsBase {    open fun f() {}}abstract class AbsDerived: AbsBase() {//    override fun f() {} //直接重写    override abstract fun f() //抽象重写,还是需要子类重写}class StableDerived : AbsDerived() {    override fun f() {    }}/*Kt中不能声明static的方法和属性 */fun main(args: Array<String>) {    val d3 = Derived3("stone")    val f1 = Foo1()    println(f1.x)//    f1.x = 1  //    val b1 = Bar1()    println(", ${b1.x}")}

 

Properties


下面代码示例了:

const定义常量属性;
var定义的属性,可以重写get/set;
val定义的属性,仅能重写get;
field 关键字;
lateinit 定义延迟初始化的属性;

package com.stone.clazzobj.propertiesfields//import kotlin.reflect.jvm.internal.impl.javax.inject.Inject/** * desc  : * author: stone * email : aa86799@163.com * time  : 01/06/2017 10 21 *///常量 必须定义在 Kotlin文件顶级, 不能定在 class或其它内部(在内部就是二级了)const val SUBSYSTEM_DEPRECATED: String = "This subsystem is deprecated"@Deprecated(SUBSYSTEM_DEPRECATED) fun foo() { }class PropertiesOperation(size: Int) {    val size = size    //var 可变,可重写 get()、set()   仅指定get()时,需要进行初始化,指定默认值; set()为默认实现    var stringRepresentation1: String = ""        get() = this.toString()    //var 重写 get()、set()    var stringRepresentation2: String        get() = this.toString()        set(value) {            setDataFromString(value) // parses the string and assigns values to other properties        }    private fun  setDataFromString(value: String) {}    //val 不可变,只能重写 get()    val isEmpty1: Boolean get() = this.size == 0    val isEmpty2 get() = this.size == 0 // has type Boolean    var setterVisibility: String = "abc"        private set // the setter is private and has the default implementation    var setterWithAnnotation: Any? = null        /*@Inject*/ set // annotate the setter with Inject    /*    使用 field 关键字,指代它所在的属性。它仅能在 属性的 get或set中使用    还有个比较形象的称呼:backing field。  向后看,就知它是指哪个属性了     */    var counter = 0 // the initializer value is written directly to the backing field        set(value) {            if (value >= 0) field = value        }    /*    backing property    使用一个私有属性 来实现当前属性的get、set     */    private var _table: Map<String, Int>? = null    val table: Map<String, Int>        get() {            if (_table == null) {                _table = HashMap() // Type parameters are inferred }                return _table ?: throw AssertionError("Set to null by another thread")            }            return _table ?: throw AssertionError("Set to null by another thread")        }}object Tes {//singleton    //针对var 属性, 延迟初始化    lateinit var str: String    fun init(arg: String) {        str = arg    }    //针对val 属性, 延迟加载    val name: String by lazy {        println("load name")        "stone86"    }}fun main(args: Array<String>) {    val gs = PropertiesOperation(3)//    gs.setterVisibility = "" //set是private的 无法访问    Tes.init("stone")    println(Tes.str)    println(Tes.name)}

这里给出一个自定义View继承View时的实现

阅读全文
0 0