Android Kotlin Classes and Objects-2

不知道如何測試下列語法可以參考如何使用Android Studio 測試資料?

  1. 幫List新增swap功能
  2. 擴充外加函式,幫助程式簡化
  3. T,多類型引入
  4. T搭配in、out使用
  5. 1個對象的object用法
  6. 類型別名
  7. 內聯類
  8. 委託

  • 1. 幫List新增swap功能
  • 快速兩資料交換參考Android Kotlin 基本語法3

    fun MutableList.swap(index1: Int, index2: Int) {
        val tmp = this[index1] 
        this[index1] = this[index2]
        this[index2] = tmp
    }
    fun MutableList.swap2(index1: Int, index2: Int) {
        //用Android Kotlin 基本語法3那篇的,快速兩資料交換的方法
        this[index1] = this[index2].also {
            this[index2] = this[index1]
        }
    }
    @Test
    fun test() {
        val list = mutableListOf(10, 20, 30)
        list.swap(0, 2) 
        list.forEach {
            println("A = $it")
        }
        /*
        打印
        A = 30
        A = 20
        A = 10*/
        list.swap2(0, 2)
        list.forEach {
            println("B = $it")
        }
        /*
        打印
        B = 10
        B = 20
        B = 30*/
    }
    

  • 2. 擴充外加函式,幫助程式簡化
  • class Host(val hostname: String) {
        fun printHostname() { print(hostname) }
    }
    
    class Connection(val host: Host, val port: Int) {
        fun printPort() { 
            print(port) 
        }
        //利用此方法幫助程式簡化
        fun Host.printConnectionString() {
            printHostname()
            print(":")
            printPort()
        }
    
        fun connect() {
            host.printConnectionString()
        }
    }
    
    @Test
    fun test() {
        Connection(Host("kotl.in"), 443).connect()
    }
    

  • 3. T,多類型引入
  • class Box(t: T) {
        var value = t
    }
    
    @Test
    fun test() {
        val box = Box("123")
    }
    

  • 4. T搭配in、out使用
  • //T搭配out用法
    interface Source {
        //in -> 引入T, out -> return T, 此處為"return T"
        fun nextT(): T
    }
    fun demo(callback: Source) {
        val objects: Source = callback 
        println(objects.nextT())//打印"hello"
    }
    val sourceCallback = object : Source{
        override fun nextT(): String {
            return "hello"
        }
    }
    @Test
    fun test() {
        demo(sourceCallback)
    }
    //T搭配in用法
    interface Comparable {
        //in -> 引入T, out -> return T, 此處為"引入T"
        fun compareTo(data1: T, data2: T): Boolean
    }
    fun demo(x: Comparable) {
        //打印false
        println(x.compareTo(1.0, 2.0)) 
        // Double是Number的子類型
    
        //因此可以這樣賦予
        val y: Comparable = x // OK!
    }
    @Test
    fun test2() {
        demo(object : Comparable{
            override fun compareTo(
                data1: Number, 
                data2: Number
            ): Boolean = data1 == data2
        })
    }
    

  • 5. 1個對象的object用法
  • class C {
        // 私有函數內,返回的函數也是私有的
        private fun foo() = object {
            val x: String = "x"
        }
    
        // 公有函數,內容也是公有
        fun publicFoo() = object {
            val x: String = "x"
        }
    
        fun bar() {
            val x1 = foo().x        
            // private fun 正常
    
            val x2 = publicFoo().x  
            // fun 錯誤
        }
    }
    

  • 6. 類型別名
  • //typealias 是重新將底層類型命名
    //testString is String
    typealias testString = String
    class ExampleUnitTest {
    
        @Test
        fun test() {
            val data: testString = "1234"
            println(data)
            //print 1234
        }
    
    }
    

    7. 內聯類,為了減少大量程式碼的開銷

    //inline在1.5版以後,不推薦使用的內聯類
    //應改為下方
    @JvmInline
    value class Password(val value: String)
    
    @Test
    fun test() {
        //securePassword運行的時候,內部會簡化成只代表String
        val securePassword = 
            Password("Don't try this in production")
        println(securePassword)
    }
    
    var counter = 0
        set(value) {
            if (value >= 0)
                field = value
            //field 就是backing fields
        }
    
    //還有支持一些基本用法
    //但有一些限制,不能含有 backing fields
    //只能做簡單的計算(沒有lateinit/delegated屬性)
    @JvmInline
    value class Name(val s: String) {
        init {
            require(s.length > 0) {
                //require <= 0
                //throw java.lang.IllegalArgumentException
            }
        }
        val length: Int
            get() = s.length
        fun greet() {
            println("Hello, $s")
        }
    }
    @Test
    fun test() {
        val name = Name("Kotlin")
        name.greet() 
        // `greet` 方法會作為一個靜態方法調用
    
        println(name.length) 
        //屬性的get方法會作為一個靜態方法調用
    }
    
    //內聯類允許繼承
    interface Printable {
        fun prettyPrint(): String
    }
    
    @JvmInline
    value class Name(val s: String) : Printable {
        override fun prettyPrint(): String = "Let's $s!"
    }
    
    @Test
    fun test() {
        val name = Name("Kotlin")
        println(name.prettyPrint()) 
        // Still called as a static method
    }
    //typealias 是重新將底層類型命名
    //@JvmInline
    //    value是生成新的類型
    typealias NameTypeAlias = String
    
    @JvmInline
    value class NameInlineClass(val s: String)
    
    fun acceptString(s: String) {}
    fun acceptNameTypeAlias(n: NameTypeAlias) {}
    fun acceptNameInlineClass(p: NameInlineClass) {}
    
    @Test
    fun test() {
        val nameAlias: NameTypeAlias = ""
        val nameInlineClass: NameInlineClass = 
            NameInlineClass("")
    
        val string: String = ""
    
        acceptString(nameAlias) 
        //正常,因為typealias 是重新將底層類型命名
    
        acceptString(nameInlineClass) 
        //錯誤,內聯是新建新的類型,所以不等於String
        
    
        // And vice versa:
        acceptNameTypeAlias(string) 
        //正常,因為typealias 是重新將底層類型命名
    
        acceptNameInlineClass(string) 
        //錯誤,內聯是新建新的類型,所以不等於String
    }
    

    8. 委託(Delegation)

    interface Base {
        val message: String
        fun print()
    }
    class BaseImpl(x: Int) : Base {
        override val message = "BaseImpl: x = $x"
        override fun print() { println(message) }
    }
    class Derived(b: Base) : Base by b {
        //by b -> 如果此處有override,以此處為優先
        //若沒有override,則使用Base內預設的.
        override val message = "Message of Derived"
    }
    @Test
    fun test() {
        val b = BaseImpl(10)
        val derived = Derived(b)
        derived.print()
        println(derived.message)
        /*
        BaseImpl: x = 10
        Message of Derived
         */
    }
    


    上面皆是版本ext.kotlin_version = “1.5.0″測試的


    更多相關可以參考這裡


    相關文章

    Android Kotlin 基本語法1Android Kotlin 基本語法2
    1. var 可變變數
    2. val 不可變更參數
    3. Array 用法
    4. ArrayList 用法
    5. List的filter、sort、map、forEach
    6. when 用法
    7. fun 函式用法
    8. if 表達式
    9. for 表達式
    10. 擴充函數(自定義函式)
    1. 操作符重載
    2. 資料區間用法
    3. map使用方法
    4. 內部靜態變數
    5. 靜態變數
    6. 當資料如果是?型態宣告
    7. 資料使用!!,強制將Int?轉Int
    8. data class用法
    9. 強制轉型
    10. run、with、apply、also用法
    Android Kotlin 基本語法3Android Kotlin 基本語法4
    1. class多建構式
    2. 內部class用法
    3. interface
    4. enum class 用法
    5. sealed class 用法
    6. open 用法
    1. 為基礎類型新增函式
    2. Abstract技巧使用
    3. throw使用方法
    4. 利用let特性處理資料型態?
    5. 快速初始化Array
    6. 快速將兩個資料交換
    7. 自定義待處理的fun
    8. 幫loop設定標籤
    Android Kotlin Classes and Objects-1Android Kotlin 委託屬性
    1. 多個class與執行順序
    2. init與constructor執行優先序
    3. open繼承與禁止繼承
    4. 不同的寫法,影響override能不能改變值
    5. 繼承與當前Class執行順序
    6. 由inner class去找parent的super
    7. 繼承多個class時,選擇指定的Parent
    8. private protected public internal修飾符差異
    1. 變數委託
    2. lazy懶加載用法+String.split
    3. 可觀察屬性observable
    4. 委託內建map
    5. 本地委託屬性,此方法可以減少加載
    6. 委託屬性,唯獨與可讀可寫的方法
    7. 將舊方法棄用

    訂閱Codeilin的旅程,若有最新消息會通知。

    廣告

    發表迴響

    在下方填入你的資料或按右方圖示以社群網站登入:

    WordPress.com 標誌

    您的留言將使用 WordPress.com 帳號。 登出 /  變更 )

    Facebook照片

    您的留言將使用 Facebook 帳號。 登出 /  變更 )

    連結到 %s

    透過 WordPress.com 建置的網站.

    向上 ↑

    %d 位部落客按了讚: