一手遮天 Android - kotlin: 类相关 2(类继承,接口,抽象类,by 委托)

项目地址 https://github.com/webabcd/AndroidDemo
作者 webabcd

一手遮天 Android - 类相关 2(类继承,接口,抽象类,by 委托)

示例如下:

/kotlin/Demo8.kt

/**
 * 本例用于演示类继承,接口,抽象类,by 委托
 */

package com.webabcd.androiddemo.kotlin

import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import com.webabcd.androiddemo.R
import kotlinx.android.synthetic.main.activity_kotlin_helloworld.*
import kotlin.reflect.KProperty

class Demo8 : AppCompatActivity() {

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_kotlin_demo8)

        sample1() // 类继承
        sample2() // 接口
        sample3() // 抽象类
        sample4() // by 委托
    }

    fun sample1() {
        var a = Demo8_Class1(40);
        appendMessage(a.hello()) // hello:wanglei, age:40, country:china

        var b = Demo8_Class2(40, "中国");
        appendMessage(b.hello()) // hi:wanglei, age:80, country:中国
    }

    fun sample2() {
        var a = Demo8_Class3(40)
        appendMessage(a.hello()) // hello:wanglei, age:40 hi:wanglei, age:40
    }

    fun sample3() {
        var a = Demo8_Class4("wanglei")
        appendMessage(a.hello()) // hello:wanglei, age:100, country:china
    }

    fun sample4() {
        // 接口的实现委托给指定的参数(通过 by 委托)
        var a = MyClass1("webabcd")
        var b = MyClass2(a)
        appendMessage("${a.hello()}, ${b.hello()}") // hello: webabcd, hello: webabcd

        // 属性的实现委托给指定的类(通过 by 委托)
        var c = MyClass3()
        c.myName = "webabcd"
        appendMessage("${c.myName}") // property name:myName, value:webabcd

        // 注:还有一种 by 委托可以用来实现属性的懒初始化,即 by lazy(请参见:Demo1.kt)
    }
    interface MyInterface {
        fun hello(): String
    }
    class MyClass1(val name: String): MyInterface {
        override fun hello(): String {
            return "hello: $name"
        }
    }
    // MyClass2 类委托 xxx 参数实现 MyInterface 接口
    // 也就是说 MyClass2 类实现了 MyInterface 接口,你在调用 MyClass2 的相关实现的时候,其实调用的是 xxx 的实现
    class MyClass2(xxx: MyInterface): MyInterface by xxx {
        // 如果你在这里实现 MyInterface 接口的某些方法的话,则这里的实现会覆盖 xxx 的实现
    }
    // myName 属性的实现委托给 MyDelegate 类
    class MyClass3 {
        var myName: String by MyDelegate()
    }
    class MyDelegate {
        private var _s: String = ""
        operator fun getValue(thisRef: Any?, property: KProperty<*>): String {
            return "property name:${property.name}, value:$_s"
        }
        operator fun setValue(thisRef: Any?, property: KProperty<*>, value: String) {
            _s = value
        }
    }



    fun appendMessage(message: String) {
        textView1.append(message)
        textView1.append("\n")
    }
}

\kotlin\Demo8_Class1.kt

/**
 * 父类(用于演示类继承)
 *
 * 可被继承的类要用 open 修饰(默认是 final 的,即不可继承)
 * 可被重写的属性或方法要用 open 修饰(默认是 final 的,即不可重写)
 */

package com.webabcd.androiddemo.kotlin

open class Demo8_Class1(var age: Int) {

    init {
        this.age = age
    }

    open var name = "wanglei"

    open var country = "china"

    open fun hello(): String {
        return "hello:$name, age:$age, country:$country"
    }
}

\kotlin\Demo8_Class2.kt

/**
 * 子类(用于演示类继承)
 */

package com.webabcd.androiddemo.kotlin

// 通过 : 继承父类,调用父类的主构造函数
// 通过类似如下 override var country: String 的方式重写父类的属性
// 注:这个类也可以被继承,因为他用 open 修饰了,如果需要这个类不可以被继承,就把 open 去掉,那么就是默认 final 了,就不能被继承了
open class Demo8_Class2(age: Int, override var country: String) : Demo8_Class1(age * 2) {

    // 如下方式,通过 super 调用非主构造函数
    // constructor(country: String): super(country)

    // 属性在父类中是 val,那么是可以在子类中改用 var 修饰的
    // 属性在父类中是 var,那么是不能在子类中改用 val 修饰的

    // 重写属性
    // 注:父类中 name 是 open 的,所以如果某个类继承了这个类,那么其是可以重写此属性的,如果不想这样,那么这里就要用 final 修饰,类似这样 final override var name...
    override var name = "wanglei"

    // 重写方法
    // 注:父类中 hello() 是 open 的,所以如果某个类继承了这个类,那么其是可以重写此方法的,如果不想这样,那么这里就要用 final 修饰,类似这样 final override fun hello(): String...
    override fun hello(): String {

        // 通过 super 调用父类的属性或方法
        // super.name
        // super.hello()

        return "hi:$name, age:$age, country:$country"
    }
}

\kotlin\Demo8_Class3.kt

/**
 * 实现类(用于演示接口)
 *
 * 接口的方法可以有自己的实现,但是属性不可以有自己的实现(需要子类实现)
 */

package com.webabcd.androiddemo.kotlin

// 通过 : 实现多个接口
// 通过类似如下 override var age: Int 的方式实现接口的属性
class Demo8_Class3(override var age: Int) : Demo8_Interface1, Demo8_Interface2 {

    init {
        this.age = age;
    }

    // 实现接口的属性
    override var name: String = ""
        get() = "wanglei"

    // 实现接口的方法
    override fun hello(): String {

        // 通过 super 调用接口的方法
        // super.hello()

        // 如果实现的多个接口有重名的方法,则可以用如下方式调用不同接口的方法
        return super<Demo8_Interface1>.hello() + " " + super<Demo8_Interface2>.hello()
    }
}

\kotlin\Demo8_Interface1.kt

/**
 * 接口 1(用于演示接口)
 *
 * 接口的方法可以有自己的实现,但是属性不可以有自己的实现(需要子类实现)
 */

package com.webabcd.androiddemo.kotlin

interface Demo8_Interface1 {

    var name: String

    var age: Int

    fun hello(): String {
        return "hello:$name, age:$age"
    }
}

\kotlin\Demo8_Interface2.kt

/**
 * 接口 2(用于演示接口)
 *
 * 接口的方法可以有自己的实现,但是属性不可以有自己的实现(需要子类实现)
 */

package com.webabcd.androiddemo.kotlin

interface Demo8_Interface2 {

    var name: String

    var age: Int

    fun hello(): String {
        return "hi:$name, age:$age"
    }
}

\kotlin\Demo8_Class4.kt

/**
 * 子类(用于演示抽象类)
 */

package com.webabcd.androiddemo.kotlin

// 通过 : 继承抽象类
// 通过类似如下 override var name: String 的方式重写抽象类的抽象属性
class Demo8_Class4(override var name: String) : Demo8_Abstract() {

    init {
        this.name = name
    }

    // 重写抽象类的抽象属性
    override var country = "china"

    // 重写抽象类的抽象方法
    override fun getAge(): Int {
        return 100;
    }
}

\kotlin\Demo8_Abstract.kt

/**
 * 抽象类(用于演示抽象类)
 */

package com.webabcd.androiddemo.kotlin

abstract class Demo8_Abstract {

    // 需要子类重写的属性
    abstract var name:String

    // 需要子类重写的属性
    abstract var country:String

    // 需要子类重写的方法
    abstract fun getAge(): Int

    // 有自己逻辑的方法,不需要子类重写
    fun hello(): String {
        return "hello:$name, age:${getAge()}, country:$country"
    }
}

/layout/activity_kotlin_demo8.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical">

    <TextView
        android:id="@+id/textView1"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content" />

</LinearLayout>

项目地址 https://github.com/webabcd/AndroidDemo
作者 webabcd

posted @ 2021-05-31 12:12  webabcd  阅读(122)  评论(0编辑  收藏  举报