kotlin学习小结1

1关于复写调用父类方法

 class SinleChild : GodClass() {
    lateinit var aa: String
    val bb by lazy { "00" }
    override var vvar: Int = 1
    override var vval: Int = 1

    override fun funff() {
        super.funff()
        print("我是child")
    }

    inner class innn {
        fun prin() {
            funff()
            super@SinleChild.funff()//调用godclass的funff方法

        }
    }
}

2覆盖规则

在 Kotlin 中,实现继承由下述规则规定:如果一个类从它的直接超类继承相同成员的多个实现, 它必须覆盖这个成员并提供其自己的实现(也许用继承来的其中之一)。 为了表示采用从哪个超类型继承的实现,我们使用由尖括号中超类型名限定的 super,如 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()
  }
}

3setter&&getter

var stringRepresentation: String
    get() = this.toString()
    set(value) {
        if (value >= 0) field = value
    }

4扩展

Kotlin 同 C# 和 Gosu 类似,能够扩展一个类的新功能而无需继承该类或使用像装饰者这样的任何类型的设计模式。 这通过叫做 扩展 的特殊声明完成。Kotlin 支持 扩展函数 和 扩展属性。

接收者可为空
fun Any?.toString(): String {
    if (this == null) return "null"
    // 空检测之后,“this”会自动转换为非空类型,所以下面的 toString()
    // 解析为 Any 类的成员函数
    return toString()
}

注意:由于扩展没有实际的将成员插入类中,因此对扩展属性来说幕后字段是无效的。这就是为什么扩展属性不能有初始化器。他们的行为只能由显式提供的 getters/setters 定义。

val <T> List<T>.lastIndex: Int
    get() = size - 1//正确

val <T> List<T>.lastIndex: Int = 1 // 错误:扩展属性不能有初始化器

5object

匿名对象可以用作只在本地和私有作用域中声明的类型。如果你使用匿名对象作为公有函数的返回类型或者用作公有属性的类型,那么该函数或属性的实际类型会是匿名对象声明的超类型,如果你没有声明任何超类型,就会是 Any。在匿名对象中添加的成员将无法访问

class C {
    // 私有函数,所以其返回类型是匿名对象类型
    private fun foo() = object {
        val x: String = "x"
    }

    // 公有函数,所以其返回类型是 Any
    fun publicFoo() = object {
        val x: String = "x"
    }

    fun bar() {
        val x1 = foo().x        // 没问题
        val x2 = publicFoo().x  // 错误:未能解析的引用“x”
    }
}

6委托

委托模式已经证明是实现继承的一个很好的替代方式, 而 Kotlin 可以零样板代码地原生支持它。 Derived 类可以通过将其所有公有成员都委托给指定对象来实现一个接口 Base

interface Base {
    val message:String
    fun printMessage()
    fun printMessageLine()
}

class BaseImpl(val x: Int) : Base {
    override val message: String="messasge"
    override fun printMessage() { print(x) }
    override fun printMessageLine() { println(x) }
}

class Derived(b: Base) : Base by b {
    //在 b 的 `print` 实现中不会访问到这个属性
    override val message: String="de=message"
    override fun printMessage() { print("abc") }
}

fun main(args: Array<String>) {
    val b = BaseImpl(10)
    print(Derived(b).message)//message
    Derived(b).printMessage()//abc
    Derived(b).printMessageLine()//10

}

7委托属性

kotlin提供标准的几种:
1延迟属性(lazy properties): 其值只在首次访问时计算;
2可观察属性(observable properties): 监听器会收到有关此属性变更的通知;
3把多个属性储存在一个映射(map)中,而不是每个存在单独的字段中
lazy

val lazyValue: String by lazy {
    println("computed!")
    "Hello"
}

fun main(args: Array<String>) {
    println(lazyValue)//computed hello
    println(lazyValue)//hello
}

observable这个在开发中可以常用

class User {
    var name: String by Delegates.observable("<no name>") {
        prop, old, new ->
        println("$old -> $new")
    }
}

fun main(args: Array<String>) {
    val user = User()
    user.name = "first"
    user.name = "second"
}

这个例子输出:
<no name> -> first
first -> second

map

class User(val map: Map<String, Any?>) {
    val name: String by map
    val age: Int     by map
}
val user = User(mapOf(
    "name" to "John Doe",
    "age"  to 25
))
println(user.name) // Prints "John Doe"
println(user.age)  // Prints 25

这也适用于 var 属性,如果把只读的 Map 换成 MutableMap 的话:
class MutableUser(val map: MutableMap<String, Any?>) {
    var name: String by map
    var age: Int     by map
}

为了涵盖这些(以及其他)情况,Kotlin 支持 委托属性:

class Example {
    var p: String by Delegate()
}
class Delegate {
    operator fun getValue(thisRef: Any?, property: KProperty<*>): String {
        return "$thisRef, thank you for delegating '${property.name}' to me!"
    }
 
    operator fun setValue(thisRef: Any?, property: KProperty<*>, value: String) {
        println("$value has been assigned to '${property.name}' in $thisRef.")
    }
}
val e = Example()
println(e.p)//Example@33a17727, thank you for delegating ‘p’ to me!
e.p = "NEW"//NEW has been assigned to ‘p’ in Example@33a17727.

this 的用法

要访问来自外部作用域的this(一个 或者扩展函数, 或者带标签的带接收者的函数字面值)我们使用this@label,其中 @label 是一个代指 this 来源的标签:

class A { // 隐式标签 @A
    inner class B { // 隐式标签 @B
        fun Int.foo() { // 隐式标签 @foo
            val a = this@A // A 的 this
            val b = this@B // B 的 this

            val c = this // foo() 的接收者,一个 Int
            val c1 = this@foo // foo() 的接收者,一个 Int

            val funLit = lambda@ fun String.() {
                val d = this // funLit 的接收者
            }


            val funLit2 = { s: String ->
                // foo() 的接收者,因为它包含的 lambda 表达式
                // 没有任何接收者
                val d1 = this
            }
        }
    }
}

9==,equlas,===

==

  1. 如果作用于基本数据类型的变量,则直接比较其存储的 “值”是否相等2. 如果作用于引用类型的变量,则比较的是所指向的对象的地址

equals

  1. equals方法不能作用于基本数据类型的变量2. 如果没有对equals方法进行重写,则比较的是引用类型的变量所指向的对象的地址;
    3.诸如String、Date等类对equals方法进行了重写的话,比较的是所指向的对象的内容。

===

  1. 对于基本数据类型,如果类型不同,其结果就是不等。如果同类型相比,与“==”一致,直接比较其存储的 “值”是否相等;2. 对于引用类型,与“==”一致,比较的是所指向的对象的地址
fun main(args: Array<String>) {

    val a : Int = 10
    val b : Long = 10
    val c : Int = 20
    val d : String = "abc"
    val e : String = "abcd"
    val f : String = d

    val ooA : Operator = Operator("zhang", 10)
    val ooB : Operator = Operator("li", 20)
    val ooC : Operator = Operator("zhang", 10)
    val ooD : Operator = ooA
    // ==
    println("-------- == -------- ")
    println("a == c: ${a==c}")
    println("ooA == ooC: ${ooA==ooC}")
    println("ooA == ooD: ${ooA==ooD}")
    println("d == e: ${d==e}")
    println("f == d: ${f==d}")

    // equals
    println("-------- equals -------- ")
    println("ooA.equals(ooC): ${ooA.equals(ooC)}")
    println("d.equals(e): ${d.equals(e)}")

    // ===
    println("-------- === -------- ")
    println("a === c: ${a===c}")
    println("ooA === ooC: ${ooA===ooC}")
    println("ooA === ooD: ${ooA===ooD}")
    println("d === e: ${d===e}")
}

data class Operator(var name: String, var age: Int) {

    override fun equals(other: Any?): Boolean {
        if (other is Operator) {
            return this.age == other.age
        }
        return false
    }
}

a == c: false
ooA == ooC: true
ooA == ooD: true
d == e: false
f == d: true
-------- equals --------
ooA.equals(ooC): true
d.equals(e): false
-------- === --------
a === c: false
ooA === ooC: false
ooA === ooD: true
d === e: false

10构造函数

构造函数分为主构造函数和次构造函数,主构造函数一般写在类名后,次构造函数要委托给主构造函数

class ChildClass(age: Int){

    private var age: Int

    init {
        //主构造函数里不能写代码,需要在init中
        this.age=age
    }

    private lateinit var name: String

    constructor(name: String):this(0){
      this.name=name
  }

    private var b: Boolean=false

    constructor(name: String, b: Boolean):this(name){
        this.b=b
    }
}

构造函数的继承

1 无主构造函数
class MyView : View(){

    constructor(context: Context) : super(context)

    constructor(context: Context, attrs: AttributeSet?) : super(context, attrs)

    constructor(context: Context, attrs: AttributeSet?, defStyleAttr: Int)
        : super(context, attrs, defStyleAttr)
}

2.存在主构造函数
主构造函数一般实现基类型中参数最多的构造函数,参数少的构造函数则用 this 关键字引用即可了
class MyView(context: Context?, attrs: AttributeSet?, defStyleAttr: Int)
    : View(context, attrs, defStyleAttr) {

    constructor(context: Context?) : this(context,null,0)
    
    constructor(context: Context?,attrs: AttributeSet?) : this(context,attrs,0)
}

构造函数的参数加上 var 和 val 是一种简洁的写法,意思是将该变量作为类的成员变量来使用:不是所有的构造函数都能用var和val修饰的,只有在主构造函数上才能使用,这只是声明属性以及从主构造函数初始化属性的一种简洁的语法。事实上你不能在次构造函数和其他函数上使用该语法,因为你不能在这些地方声明类的属性。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 194,491评论 5 459
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 81,856评论 2 371
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 141,745评论 0 319
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 52,196评论 1 263
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 61,073评论 4 355
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 46,112评论 1 272
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 36,531评论 3 381
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 35,215评论 0 253
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 39,485评论 1 290
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 34,578评论 2 309
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 36,356评论 1 326
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 32,215评论 3 312
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 37,583评论 3 299
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 28,898评论 0 17
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,174评论 1 250
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 41,497评论 2 341
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 40,697评论 2 335

推荐阅读更多精彩内容