国产亚洲精品福利在线无卡一,国产精久久一区二区三区,亚洲精品无码国模,精品久久久久久无码专区不卡

當前位置: 首頁 > news >正文

游戲服務器網(wǎng)站seo推廣招聘

游戲服務器,網(wǎng)站seo推廣招聘,山東省政府采購與招標網(wǎng)官網(wǎng),簡單的企業(yè)網(wǎng)站建設(shè)教程前言 本篇文章將帶您了解Kotlin編程中的重要概念:類及構(gòu)造函數(shù)、訪問修飾符、伴生對象和單例模式。就像搭積木一樣,我們會逐步揭開這些概念的面紗,讓您輕松理解它們的作用和用法。無論您是編程新手還是有經(jīng)驗的開發(fā)者,本文都將為…

前言

本篇文章將帶您了解Kotlin編程中的重要概念:類及構(gòu)造函數(shù)、訪問修飾符、伴生對象和單例模式。就像搭積木一樣,我們會逐步揭開這些概念的面紗,讓您輕松理解它們的作用和用法。無論您是編程新手還是有經(jīng)驗的開發(fā)者,本文都將為您提供有趣而易懂的內(nèi)容,幫助您更好地掌握Kotlin中類與對象的重要知識點。讓我們一起開始這段有趣的學習之旅吧!

一、Kotlin 的類以及構(gòu)造函數(shù)

1、聲明一個類

當你使用 class 關(guān)鍵字在 Kotlin 中聲明一個類時,其基本的語法格式如下所示:

class ClassName {// 類的成員變量和方法在這里定義
}

2、關(guān)于Kotlin類的繼承和接口實現(xiàn)的規(guī)則

(1)繼承父類

如果一個類有父類,你可以在類的聲明中使用冒號 : 后面跟著父類的名稱。這稱為類的繼承。例如:

import android.os.Bundle
import androidx.appcompat.app.AppCompatActivityclass MainActivity : AppCompatActivity() {override fun onCreate(savedInstanceState: Bundle?) {super.onCreate(savedInstanceState)setContentView(R.layout.activity_main)// 在這里可以進行一些初始化操作}
}
  • 繼承父類無參構(gòu)造函數(shù):如果父類有一個無參構(gòu)造函數(shù),子類可以省略括號,并且不需要在子類中聲明構(gòu)造函數(shù)。這適用于父類的構(gòu)造函數(shù)沒有參數(shù)的情況,或者所有參數(shù)都有默認值。

  • 繼承父類有參構(gòu)造函數(shù):如果父類的構(gòu)造函數(shù)有參數(shù),或者你想在子類中添加自己的構(gòu)造函數(shù),就需要根據(jù)具體情況使用括號并傳遞必要的參數(shù)。

(2)默認父類

如果一個類沒有顯式聲明父類,它的默認父類是 Any 類,而不是 Object 類。Any 是 Kotlin 根類層次結(jié)構(gòu)的頂層類型。所有的 Kotlin 類都直接或間接地繼承自 Any 類。

Any 類的聲明如下:

public open class Any

在 Kotlin 中,默認情況下,所有類都隱式地繼承自 Any 類,即使你沒有明確指定。因此,以下兩個類聲明是等價的:

class MyClass
class MyClass : Any()

這就是為什么你在 Kotlin 中無需顯式指定父類,而默認情況下所有類都已經(jīng)繼承自 Any。

需要注意的是,Any 類定義了一些通用方法,如 equalshashCodetoString,因此所有的 Kotlin 類都會具備這些方法。

(3)接口實現(xiàn)

在 Kotlin 中,可以在類的聲明后面使用冒號 : 來實現(xiàn)一個或多個接口。你不需要顯式使用 implements 關(guān)鍵字。例如:

import android.os.Bundle
import android.view.View
import android.widget.Button
import androidx.appcompat.app.AppCompatActivityclass MainActivity : AppCompatActivity(), View.OnClickListener {override fun onCreate(savedInstanceState: Bundle?) {super.onCreate(savedInstanceState)setContentView(R.layout.activity_main)val button = findViewById<Button>(R.id.button)button.setOnClickListener(this)}override fun onClick(v: View?) {when (v?.id) {R.id.button -> {// 在這里定義按鈕點擊事件的邏輯}}}
}

在上面的示例中,我們首先讓 MainActivity 類實現(xiàn)了 View.OnClickListener 接口,并重寫了其中的 onClick 方法。然后,我們在 onCreate 方法中使用 setOnClickListener(this) 將當前 MainActivity 對象作為按鈕的點擊監(jiān)聽器。

在 Kotlin 中,你是可以先寫接口后寫父類,或者先寫父類后寫接口,都是完全合法的。在類的聲明中,繼承父類和實現(xiàn)接口的順序可以根據(jù)你的需求進行靈活安排。

3、open 關(guān)鍵字的作用

在 Kotlin 中,默認情況下,類是 publicfinal 的,這意味著它們對外部可見,并且不能被繼承。如果你希望其他類能夠繼承這個類,你需要使用 open 關(guān)鍵字來聲明這個類,使它變成可繼承的。

在 Kotlin 中,修飾符的含義如下:

  • public:表示該成員(類、函數(shù)、屬性等)在任何地方都可見。
  • final:表示類、函數(shù)或?qū)傩圆荒鼙焕^承或覆蓋(重寫),在類級別指的是類不能被繼承。
  • open:用于修飾類、函數(shù)或?qū)傩?#xff0c;表示它們可以被繼承或覆蓋。

如果你想要創(chuàng)建一個可被繼承的類,你需要使用 open 修飾符。

例如,當你想在 Android 應用中創(chuàng)建一個可被繼承的 MainActivity 類時,你需要在類的聲明前面加上 open 修飾符,以允許其他類繼承它。這樣,其他類就可以繼承 MainActivity 并在子類中進行擴展。

以下是一個示例,展示如何在 Android 應用中創(chuàng)建一個可被繼承的 MainActivity 類:

import android.os.Bundle
import androidx.appcompat.app.AppCompatActivityopen class MainActivity : AppCompatActivity() {override fun onCreate(savedInstanceState: Bundle?) {super.onCreate(savedInstanceState)setContentView(R.layout.activity_main)// 在這里可以進行一些初始化操作}
}

在這個示例中,我們創(chuàng)建了一個名為 MainActivity 的類,繼承自 AppCompatActivity,這是 Android 中用于創(chuàng)建活動(Activity)的基類。注意,在類的聲明中,我們使用了 open 修飾符,允許其他類繼承這個 MainActivity。

其他類可以繼承這個 MainActivity 并在子類中進行擴展,例如:

class CustomActivity : MainActivity() {override fun onCreate(savedInstanceState: Bundle?) {super.onCreate(savedInstanceState)// 在這里可以進行自定義的初始化操作}
}

在上面的示例中,CustomActivity 類繼承自 MainActivity,并在子類中重寫了 onCreate 方法,實現(xiàn)了自定義的初始化操作。

總結(jié),通過使用 open 修飾符,你可以在 Android 應用中創(chuàng)建一個可被繼承的基類,讓其他類能夠繼承它并在子類中添加自己的功能。

4、主構(gòu)造函數(shù)和次構(gòu)造函數(shù)

構(gòu)造函數(shù)是用于創(chuàng)建對象的特殊方法,它在對象創(chuàng)建時被調(diào)用,通常用于執(zhí)行初始化操作。在 Kotlin 中,類可以有一個主構(gòu)造函數(shù)和多個次構(gòu)造函數(shù)。

(1)主構(gòu)造函數(shù)

當涉及到在 Kotlin 類中創(chuàng)建實例時,主構(gòu)造函數(shù)扮演著重要的角色。主構(gòu)造函數(shù)允許在對象被實例化時接收參數(shù),并且對對象的屬性進行初始化。以下是關(guān)于主構(gòu)造函數(shù)的概要:

  • 聲明方式:主構(gòu)造函數(shù)是類定義的一部分,緊隨類名后面的括號中可以包含參數(shù)列表。如果主構(gòu)造函數(shù)沒有其他修飾符,那么括號可以省略。
  • 參數(shù)傳遞:主構(gòu)造函數(shù)的參數(shù)可以在整個類范圍內(nèi)使用,不僅限于初始化代碼塊。你可以將這些參數(shù)直接用于屬性的初始化。
  • 初始化代碼塊:主構(gòu)造函數(shù)也可以包含初始化代碼塊,使用 init 關(guān)鍵字定義。在這個代碼塊中,你可以編寫在對象初始化時執(zhí)行的代碼。

以下是一個示例,展示了如何聲明主構(gòu)造函數(shù)、使用參數(shù)初始化屬性,并在初始化代碼塊中執(zhí)行邏輯,其中使用了自定義視圖類 CustomView

class CustomView(context: Context, attrs: AttributeSet): View(context, attrs) {private val paint: Paint = Paint()init {paint.color = Color.BLACK}
}

在上述示例中,CustomView 類繼承自 View,并在主構(gòu)造函數(shù)中接收了 contextattributeSet 參數(shù)。

在類的主體中,聲明了一個名為 paint 的私有屬性,并在初始化時進行了屬性初始化。使用了 Paint 類,這是 Android 中用于繪制圖形和文本的工具類。

在類的 init 塊中,設(shè)置了 paint 的顏色為黑色(Color.BLACK)。這將確保 paint 對象在視圖實例化時就被配置為黑色,以便在后續(xù)的繪制操作中使用。

當創(chuàng)建 CustomView 的實例時,會觸發(fā) init 塊中的代碼執(zhí)行,從而完成屬性的初始化設(shè)置。init 塊是一個在對象實例化時執(zhí)行初始化代碼的地方,它允許你在構(gòu)造函數(shù)中接收參數(shù),并在 init 塊中執(zhí)行必要的初始化邏輯。在自定義視圖類中,你可以使用 init 塊來確保對象在使用之前處于正確的狀態(tài)。

(2)次構(gòu)造函數(shù)

次構(gòu)造函數(shù)是在 Kotlin 中用于提供額外的構(gòu)造函數(shù)選項的一種方式。它允許你在同一個類中定義多個不同參數(shù)集的構(gòu)造函數(shù),以滿足不同的初始化需求。次構(gòu)造函數(shù)通常調(diào)用主構(gòu)造函數(shù)或者其他次構(gòu)造函數(shù),確保共享的初始化邏輯被重復使用。

以下是關(guān)于次構(gòu)造函數(shù)的一些重要信息:

  • 聲明方式:次構(gòu)造函數(shù)通過 constructor 關(guān)鍵字聲明,緊隨其后的括號內(nèi)包含參數(shù)列表。次構(gòu)造函數(shù)可以有不同的參數(shù)集,但不能直接初始化屬性。
  • 調(diào)用主構(gòu)造函數(shù):在次構(gòu)造函數(shù)內(nèi)部,你可以使用 this() 調(diào)用主構(gòu)造函數(shù),確保共享的初始化邏輯被執(zhí)行。調(diào)用主構(gòu)造函數(shù)時,可以傳遞相應的參數(shù)。
  • 調(diào)用其他次構(gòu)造函數(shù):在次構(gòu)造函數(shù)內(nèi)部,你也可以使用 this() 調(diào)用同一個類中的其他次構(gòu)造函數(shù)。這樣可以避免重復編寫初始化邏輯。

以下是一個示例,展示了如何在 CustomView 類中使用次構(gòu)造函數(shù):

class CustomView : View {constructor(context: Context) : this(context, null, 0)constructor(context: Context, attrs: AttributeSet?) : this(context, attrs, 0)constructor(context: Context, attrs: AttributeSet?, defStyleAttr: Int) : super(context, attrs, defStyleAttr) {initialize(context, attrs, defStyleAttr)}private fun initialize(context: Context, attrs: AttributeSet?, defStyleAttr: Int) {// 在這里執(zhí)行初始化操作}}

在上面的示例中,CustomView 類繼承自 Android 中的 View 類,并且有三個構(gòu)造函數(shù):

  • 第一個構(gòu)造函數(shù)接收一個 context 參數(shù),這是主構(gòu)造函數(shù)。它通過調(diào)用次構(gòu)造函數(shù),為 attrsdefStyleAttr 提供默認值。
  • 第二個構(gòu)造函數(shù)接收 contextattrs 參數(shù),調(diào)用了具有更多參數(shù)的次構(gòu)造函數(shù)。
  • 第三個構(gòu)造函數(shù)接收 contextattrsdefStyleAttr 參數(shù),它是主要的構(gòu)造函數(shù)。它通過調(diào)用父類 View 的構(gòu)造函數(shù)來實現(xiàn),并在構(gòu)造函數(shù)內(nèi)部調(diào)用了 initialize 函數(shù)來執(zhí)行額外的初始化操作。

(3)大家來找茬

可以嘗試將下面示例代碼放到編譯器中,會發(fā)現(xiàn)編譯不通過, super 處會提示 “Primary constructor call expected”。問題出在了哪里?

class CustomView(context: Context) : View(context) {constructor(context: Context, attrs: AttributeSet?) : this(context, attrs, 0) {initialize(context, attrs, 0)}constructor(context: Context, attrs: AttributeSet?, defStyleAttr: Int) : super(context, attrs, defStyleAttr) {initialize(context, attrs, defStyleAttr)}private fun initialize(context: Context, attrs: AttributeSet?, defStyleAttr: Int) {// 在這里執(zhí)行初始化操作}}

錯誤消息 “Primary constructor call expected” 意味著在構(gòu)造函數(shù)的調(diào)用位置需要調(diào)用主構(gòu)造函數(shù),但實際上沒有調(diào)用。

在 Kotlin 中,如果一個類有一個主構(gòu)造函數(shù),那么所有的次構(gòu)造函數(shù)必須委托給主構(gòu)造函數(shù)。這是語言的規(guī)定,確保類的初始化能夠始終通過主構(gòu)造函數(shù)完成。

在我們的代碼中,主構(gòu)造函數(shù)是 class CustomView(context: Context) : View(context) 這一行。由于它是一個主構(gòu)造函數(shù),所有的次構(gòu)造函數(shù)必須通過 this() 來調(diào)用主構(gòu)造函數(shù)。因此,不能在次構(gòu)造函數(shù)中使用 super 關(guān)鍵字來調(diào)用父類的構(gòu)造函數(shù)。

以下是修正后的代碼示例,滿足了 Kotlin 的構(gòu)造函數(shù)規(guī)定:

class CustomView(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)init {initialize(context, attrs, defStyleAttr)}private fun initialize(context: Context, attrs: AttributeSet?, defStyleAttr: Int) {// 在這里執(zhí)行初始化操作}
}

在這個修正后的代碼中,主構(gòu)造函數(shù)是 class CustomView(context: Context, attrs: AttributeSet?, defStyleAttr: Int) : View(context, attrs, defStyleAttr) ,并且所有的次構(gòu)造函數(shù)都通過 this() 來委托主構(gòu)造函數(shù)。統(tǒng)一在 init 添加初始化操作,以滿足我們的需求。

(4)@JvmOverloads 注解

使用了 @JvmOverloads 注解來為 CustomView 類的構(gòu)造函數(shù)生成所有可能的參數(shù)組合,以簡化構(gòu)造函數(shù)的使用。這樣,你可以使用主構(gòu)造函數(shù),也可以選擇性地使用次構(gòu)造函數(shù)。

我們將上述代碼再次改造一下:

class CustomView @JvmOverloads constructor(context: Context,attrs: AttributeSet? = null,defStyleAttr: Int = 0
) : View(context, attrs, defStyleAttr) {init {initialize(context, attrs, defStyleAttr)}private fun initialize(context: Context, attrs: AttributeSet?, defStyleAttr: Int) {// 在這里執(zhí)行初始化操作}
}

使用這個示例,你可以這樣創(chuàng)建一個 CustomView 實例:

val customView1 = CustomView(context)  
val customView2 = CustomView(context, attrs)  
val customView3 = CustomView(context, attrs, defStyleAttr)  

@JvmOverloads 是 Kotlin 中的一個注解,用于在編譯器級別生成多個重載版本的函數(shù)或構(gòu)造函數(shù),以便在 Java 代碼中更方便地使用。這個注解通常用于改善 Kotlin 類在 Java 代碼中的互操作性。

在特定情況下,Kotlin 的函數(shù)或構(gòu)造函數(shù)可能具有默認參數(shù),這使得在 Kotlin 中調(diào)用它們非常方便,因為可以省略部分參數(shù)。但在 Java 中,調(diào)用具有默認參數(shù)的 Kotlin 函數(shù)會變得不那么直觀,因為 Java 不直接支持 Kotlin 的默認參數(shù)語法。

這時,@JvmOverloads 就派上用場了。當你在 Kotlin 函數(shù)或構(gòu)造函數(shù)上使用 @JvmOverloads 注解時,Kotlin 編譯器會自動為每個省略參數(shù)的版本生成一個重載版本,以便在 Java 代碼中使用。這樣,Java 開發(fā)者就可以根據(jù)需要傳遞不同數(shù)量的參數(shù),而不必理解或設(shè)置 Kotlin 的默認參數(shù)。

具體來說,對于構(gòu)造函數(shù)來說,@JvmOverloads 會在編譯時為每個可能的參數(shù)組合生成一個單獨的構(gòu)造函數(shù),以確保 Java 開發(fā)者能夠使用所有參數(shù)組合。

總結(jié):@JvmOverloads 是一個用于改善 Kotlin 代碼在 Java 中互操作性的注解,它為具有默認參數(shù)的函數(shù)或構(gòu)造函數(shù)生成重載版本,使得 Java 開發(fā)者能夠更方便地使用這些函數(shù)或構(gòu)造函數(shù)。

(5)init 函數(shù),父類的構(gòu)造函數(shù)與次構(gòu)造函數(shù)之間調(diào)用順序

  • 首先,會執(zhí)父類的 init 塊(如果有的話)
  • 其次,會執(zhí)行父類的構(gòu)造函數(shù)(主構(gòu)造函數(shù)或者被次構(gòu)造函數(shù)調(diào)用的構(gòu)造函數(shù))。
  • 然后,會執(zhí)行當前類的 init 塊(如果有的話)。
  • 最后,會執(zhí)行當前類的次構(gòu)造函數(shù)(如果有的話)。

以下是一個示例來說明這個調(diào)用順序:

open class Parent {init {println("Parent's init block")}constructor() {println("Parent's constructor")}
}class Child : Parent {constructor() : super() {println("Child's constructor")}init {println("Child's init block")}
}fun main() {val obj = Child()
}

在這個示例中,當創(chuàng)建 Child 類的實例時,首先會調(diào)用 Parent 類的 init 塊,其次是 Parent 類的構(gòu)造函數(shù),然后執(zhí)行 Child 類的 init 塊,最后執(zhí)行 Child 類的次構(gòu)造函數(shù)。因此,輸出將是:

Parent's init block
Parent's constructor
Child's init block
Child's constructor

二、訪問修飾符

在 Kotlin 中,訪問修飾符用于控制類、接口、函數(shù)、屬性等成員的可見性。Kotlin 提供了一些訪問修飾符,用于指定成員在哪些范圍內(nèi)可見。以下是常見的訪問修飾符:

  1. public(默認):沒有顯式指定訪問修飾符時,默認為 public。在這種情況下,成員對所有其他代碼都可見。
  2. private:成員只在聲明它的文件中可見。私有成員對同一文件中的其他類都不可見。
  3. protected:成員在聲明它的類及其子類中可見。但在同一包內(nèi)的其他類中不可見。
  4. internal:成員對于同一模塊內(nèi)的所有代碼都可見。模塊是一組一起編譯的 Kotlin 文件。它更多的去用于我們現(xiàn)在做一些項目的結(jié)構(gòu)化的擴展的時候去使用這個修飾符。

示例:

class MyClass {private val privateVar = 1protected val protectedVar = 2internal val internalVar = 3val publicVar = 4 // 默認為 public
}fun main() {val obj = MyClass()println(obj.internalVar) // 可以訪問,因為處于同一模塊內(nèi)println(obj.publicVar)   // 可以訪問,因為是 public// 下面的代碼不能編譯通過,因為 private 和 protected 變量不在可見范圍內(nèi)// println(obj.privateVar)// println(obj.protectedVar)
}

注意:

  • 對于頂層聲明(不在類內(nèi)部的聲明),只有 publicinternal 修飾符有效。
  • internal 修飾符在 Kotlin 中非常有用,它允許模塊內(nèi)的代碼訪問成員,同時限制了模塊之間的訪問。
  • privateprotected 對于頂層聲明(不在類內(nèi)部的聲明)是無效的,因為它們只對類內(nèi)部的成員可見性起作用。

綜上所述,訪問修飾符用于控制代碼中成員的可見性范圍,確保代碼的封裝和安全性。

補充一下,什么是模塊?

每當創(chuàng)建一個 module,這就是一個模塊。如果你的一個變量名通過internal修飾的話,在同一個模塊內(nèi)的時候,是可以互相調(diào)用的,但是跨模塊的話,你是無法訪問到這個變量的。這就是 kotlin 的這個訪問修飾符,它更多的去用于我們現(xiàn)在做一些項目的結(jié)構(gòu)化的擴展的時候去使用這個修飾符。

在這里插入圖片描述

三、伴生對象

在 Kotlin 中,每個類都可以有一個伴生對象(Companion Object),它是該類的一個特殊對象實例。伴生對象的成員可以像 Java 靜態(tài)成員一樣在類級別上訪問,不需要通過類的實例來調(diào)用。伴生對象通常用于創(chuàng)建類級別的靜態(tài)成員、工廠方法、單例模式等。

在 JAVA 中,我們經(jīng)??吹竭@樣的一段代碼,就是工具類,里面定義了一些的靜態(tài)方法,可以直接用工具類的類名 . 方法名,去調(diào)用它。如下所示:

public class StringUtils {public static final String EMPTY = "";public static boolean isEmpty(CharSequence cs) {return cs == null || cs.length() == 0;}public static boolean isNotEmpty(CharSequence cs) {return !StringUtils.isEmpty(cs);}
}

但是在 kotlin 中是沒有靜態(tài)方法的,Kotlin 要怎么改寫呢?

方法有兩種,第一種辦法是我們在《Kotlin 代碼與 Java 代碼集成》中介紹過,使用 @JvmStatic 注釋暴露 Kotlin 類的靜態(tài)方法。

那么第二種方法就是現(xiàn)在要介紹的伴生對象 Companion Object ,它必須被寫在一個類的內(nèi)部,作為這個類的伴生對象。伴生對象可以包含成員函數(shù)、屬性和初始化代碼塊,類似于 Java 中的靜態(tài)成員。它的一個主要作用是允許在不創(chuàng)建類實例的情況下訪問這些成員,就像訪問靜態(tài)成員一樣。

那么我們來改寫一下:

class StringUtils {companion object {const val EMPTY = ""fun isEmpty(cs: CharSequence?): Boolean {return cs.isNullOrEmpty()}fun isNotEmpty(cs: CharSequence?): Boolean {return !isEmpty(cs)}}
}

在上面的示例中,StringUtils 類中定義了一個伴生對象,其中包含一個常量 EMPTY 和 兩個方法isEmptyisNotEmpty。那么就可以在類級別上直接訪問伴生對象的成員和方法,就像訪問類的靜態(tài)成員和靜態(tài)方法一樣。

在 Java 代碼中調(diào)用,如下所示:

 public class JavaExample {public static void main(String[] args) {String str = "";boolean isEmpty = StringUtils.Companion.isEmpty(str);boolean isNotEmpty = StringUtils.Companion.isNotEmpty(str);System.out.println("isEmpty: " + isEmpty);System.out.println("isNotEmpty: " + isNotEmpty);}
}

注意,StringUtils.Companion 中的 Companion 是伴生對象的默認名稱,因為我們并未顯式地為我們的伴生對象命名,伴生對象的名稱可以省略,那么此時使用默認的名稱 Companion

實際上伴生對象在編譯好以后會在這個類的內(nèi)部生成一個靜態(tài)對象。叫companion的對象,那么我們Java在調(diào)用的時候,實際上是通過這個類的companion對象去調(diào)用companion內(nèi)部的一些變量。

如果你為伴生對象顯式命名,例如 MyCompanion,那么需要使用該名稱來訪問伴生對象的成員。以下是一個使用了命名伴生對象的示例:

class StringUtils {companion object MyCompanion {const val EMPTY = ""fun isEmpty(cs: CharSequence?): Boolean {return cs.isNullOrEmpty()}fun isNotEmpty(cs: CharSequence?): Boolean {return !isEmpty(cs)}}
}

在 Java 代碼中調(diào)用,如下所示:

 public class JavaExample {public static void main(String[] args) {String str = "";boolean isEmpty = StringUtils.MyCompanion.isEmpty(str);boolean isNotEmpty = StringUtils.MyCompanion.isNotEmpty(str);System.out.println("isEmpty: " + isEmpty);System.out.println("isNotEmpty: " + isNotEmpty);}
}

四、單例

半生對象在 Kotlin 中還有一個非常有用的特性,就是可以用于聲明單例。在前面的文章中,我們已經(jīng)介紹了通過 object 關(guān)鍵字來創(chuàng)建匿名的內(nèi)部類,這種方式其實也可以用來實現(xiàn)單例。然而,更加推薦的寫法是利用伴生對象來創(chuàng)建單例。

使用伴生對象來實現(xiàn)單例具有許多優(yōu)點:

  1. 線程安全: 伴生對象的屬性和方法在類加載時進行初始化,確保了線程安全。這樣即使在多線程環(huán)境下也能保證只有一個實例被創(chuàng)建。
  2. 延遲初始化: 伴生對象的屬性和方法是在首次訪問時才會被初始化,這也被稱為"惰性初始化"。這種方式能夠節(jié)省資源,只有在實際需要時才會創(chuàng)建實例。
  3. 清晰可見: 伴生對象使得單例模式的實現(xiàn)更加清晰和易于理解。它將單例的代碼組織在一起,使得代碼結(jié)構(gòu)更加整潔。

總的來說,雖然在 Kotlin 中可以使用 object 關(guān)鍵字來創(chuàng)建單例,但更加推薦使用伴生對象來實現(xiàn)。這種方式不僅更加優(yōu)雅,還能夠帶來諸多優(yōu)勢,如線程安全和延遲初始化等。如果你正在考慮實現(xiàn)單例模式,不妨考慮使用伴生對象來達到更好的效果。

以下是如何使用伴生對象來實現(xiàn)單例模式的示例:

class Single private constructor() {companion object {fun get(): Single {return Holder.instance}}private object Holder {val instance = Single()}
}
  • Single 類的主構(gòu)造函數(shù)被聲明為私有,這意味著外部無法直接通過構(gòu)造函數(shù)來實例化該類。
  • Single 類的伴生對象中,我們定義了一個名為 get 的方法,用于獲取 Single 類的單例實例。該方法返回了一個 Holder 內(nèi)部對象的實例,這是通過 Holder.instance 訪問的。
  • 內(nèi)部的 Holder 對象的實例化是通過 Kotlin 中的對象聲明(object)實現(xiàn)的。由于 Kotlin 的對象聲明在首次訪問時就會被初始化,且只會被初始化一次,這確保了線程安全的單例創(chuàng)建。

上述代碼展示了一種在 Kotlin 中使用伴生對象來創(chuàng)建單例的方式,這是一種非常常見的做法。這種方式結(jié)合了私有的主構(gòu)造函數(shù)和內(nèi)部對象,確保了單例的線程安全性和延遲初始化。

http://aloenet.com.cn/news/38003.html

相關(guān)文章:

  • 做網(wǎng)站服裝app試分析網(wǎng)站推廣和優(yōu)化的原因
  • 成品網(wǎng)站源碼免費小說網(wǎng)站排名
  • 網(wǎng)站空間在哪買好微信管理系統(tǒng)登錄入口
  • 外貿(mào)網(wǎng)站如何做的好處站長工具seo綜合查詢怎么使用的
  • 手機網(wǎng)站推薦深圳seo優(yōu)化服務
  • 武漢網(wǎng)站優(yōu)化方案網(wǎng)絡推廣十大平臺
  • 怎樣獲得做網(wǎng)站的客戶信息發(fā)布平臺推廣有哪些
  • 濰坊仿站定制模板建站圖片外鏈上傳網(wǎng)站
  • 實名網(wǎng)站審核中心網(wǎng)站建設(shè)與網(wǎng)頁設(shè)計制作
  • 網(wǎng)站建設(shè)公司巨頭泰州seo推廣
  • 網(wǎng)站設(shè)計 app開發(fā)優(yōu)化關(guān)鍵詞排名公司
  • 網(wǎng)站制作論壇網(wǎng)站推廣怎么弄
  • 松山湖仿做網(wǎng)站關(guān)聯(lián)詞有哪些四年級
  • 中國建設(shè)銀行官網(wǎng)站代發(fā)工資濰坊關(guān)鍵詞優(yōu)化軟件
  • 中國建設(shè)銀行濟南招聘信息網(wǎng)站google搜索app下載
  • WordPress金融網(wǎng)站seo課程排行榜
  • 視頻網(wǎng)站如何做seo如何做電商賺錢
  • 四川省建設(shè)信息網(wǎng)站貴州seo學校
  • 南昌網(wǎng)站建設(shè)培訓班seo優(yōu)化基礎(chǔ)教程pdf
  • qq整人網(wǎng)站怎么做百度首頁百度一下
  • 新鄉(xiāng)營銷型網(wǎng)站建設(shè)產(chǎn)品營銷推廣策略
  • 百度站長怎么做網(wǎng)站維護二級域名查詢?nèi)肟?/a>
  • 一學一做看視頻網(wǎng)站網(wǎng)站推廣的渠道有哪些
  • 做網(wǎng)站頁面該建多大的畫布以圖搜圖百度識圖
  • 做網(wǎng)站用java還是c語言專業(yè)推廣引流團隊
  • 網(wǎng)站維護一般多久上海優(yōu)化外包
  • 法院文化建設(shè)網(wǎng)站女孩短期技能培訓班
  • 網(wǎng)站后臺管理系統(tǒng)制作教程長春網(wǎng)站優(yōu)化哪家好
  • 營銷型網(wǎng)站制作哪家好網(wǎng)絡營銷的特點
  • 網(wǎng)站建設(shè)方案及預算百度上做優(yōu)化一年多少錢