iT邦幫忙

2022 iThome 鐵人賽

DAY 21
0
Mobile Development

新手向Android&Kotlin學習紀錄30天系列 第 21

第21天 Kotlin小學堂(10) : Class 類別

  • 分享至 

  • xImage
  •  

類別是什麼

在物件導向語言的世界中,類別可以說是核心。
有人形容類別像藍圖、設計圖,對某類特定事物的設計,針對這類事物定義的是包含哪些資料、可以做哪些事。定義完成後的class便可以將其實例化,也就是實現藍圖成為一個物件。
舉例來說,人、車、動物、建築、遊戲玩家...等都可以封裝在類別中做設計,人會有姓名、年紀等屬性,車子會有品牌、顏色等屬性,這些屬性通常會是名詞,並且每個類還可以有屬於該類別會有的行為,人會吃會睡、車子會跑會停...等,這些行為都可以用函數來定義,而函數名通常會用動詞。

建立新的class

打開IntelliJ專案結構,在其中的src/main/kotlin資料夾上點選滑鼠右鍵->New->kotlin class

然後New Kotlin Class視窗中選擇Class選項,並替 class 命名即可,採用大駝峰式命名,這裡我輸入Robot作為類別的名稱,就這樣建立完成囉,在kotlin資料夾可以看到這個檔案。

在哪裡定義

接續剛剛創建好新的class.kt檔後,打開該檔案應該就會有同名的class了,如下:

class Robot{ }

類別通常像這樣,位於一個同名的檔案中,但kotlin也允許兩者不同名。並可以在同一檔案中定義多個類別(如果是具有類似功能的類別的話)。

建構函數

一個類別可以有一個主建構函數和多個次建構函數,每個類別一開始都是預設一個空的建構函數(),上面Robot類別的建構函數()因為沒有參數的主建構函數所以被省略。

但實例化時就算建構函數沒有參數也不能省略小括號喔。比如 : val robot = Robot()

我們呼叫建構函數時,它會負責將類別實例化,並且建構函數還允許我們傳入客製化初始值,以便實例化時指派給類別屬性當初始值。

繼續看看怎麼定義主建構函數,這將是我們最常使用的建構函數。

主建構函數是類別表頭的一部分

如果主構造函數沒有任何註解或可見性修飾符,可以省略這個constructor 關鍵字。主構造函數不能包含任何的程式碼。
主構造函數定義需要的參數_type_color,便於呼叫時傳入引數。這兩個臨時變數也提供類別屬性typecolor當初始值。

變數名稱前加底線「_」是為了便於辨識臨時變數及只參照一次的參數。

//不省略constructor
class Robot constructor(_type:String,_color:String){
    val type =_type
    val color = _color 
} 
//省略constructor
class Robot(_type:String,_color:String){
    val type = _type
    val color = _color
}

類別屬性

typecolor定義在類別中的變數就叫類別屬性,可以說是這個類別具有的特徵。而屬性一被定義,kotlin就會自動產生一個field、一個getter、一個setter:

  • field : 不允許直接定義,kotlin會封裝field保護裡面的資料,只向getter和setter開放。
  • getter方法 : 每個屬性都有,getter決定如何讀取屬性值。
  • setter方法 : 只有var關鍵字定義的屬性才會有setter。val關鍵字建立的屬性是只可讀所以不會有setter。

Kotlin會提供預設的getter、setter,但也可以覆寫他們來達到客製化。

實例化

當類別都定義好了,我們就可以試著在同一個檔案中class Robot以外的地方呼叫main函數,並在其中建立Robot的實例,如下:

class Robot(...){...}

fun main() {
    //實例化了名字叫robotCat的貓型機器人並且是藍色的。
    val robotCat = Robot("cat","blue")
    //使用「.」句點運算子來取得屬性值。
    println("type : ${robotCat.type} , color : ${robotCat.color}")
    //結果: type : cat , color : blue
}

類別函數

除了兩個類別屬性外,我們的機器人類別應該也要設計一些功能吧。屬性跟函數沒有設置先後順序的問題,單獨只有兩者之一也ok。

class Robot(_type : String, _color : String) {
    val type =_type
    val color = _color
//加入work函數,work()被呼叫時簡單在控制台印出字串
    fun work(){
        println("機器人正執行您的指令")
    }
}

main函數中,使用「.」句點運算子呼叫work()看看 : 類別名.函數名()

fun main() {
    val robotCat = Robot("cat","blue")
   
    robotCat.work()  //結果 : 機器人正執行您的指令
}

直接在主建構函數中定義屬性

定義類別屬性這件事,kotlin提供了更簡便的方式,直接在主建構函數中定義,修改Robot類別試試:

class Robot(var type : String , var color : String) {
    //刪除 val type =_type  
    //刪除 val color = _color

    fun work(){
        println("機器人正執行您的指令")
    }
}

一切如此清爽,改好後再次運行main函數,應該一切完好如初。

次建構函數

一開始有說一個類別可以有多個次建構函數,如果已經定義主建構函數的情況下,代表著建立實例都必須透過它,次建構函數就是多了一種建立實例的方法(但仍須滿足主建構函數,意思是次建構函數必須直接或間接調用主建構函數)。

// 我多加了一個電池續航力的屬性batteryLife
class Robot(val type: String,
            val color: String,
            val batteryLife: Int) {
    // 次建構函數: 
    constructor(type: String) : this(type, color = "yellow", batteryLife = 72)

   fun work(){...}
}

次建構函數通過constructor關鍵字定義。
上面次建構函數中的this關鍵字指的是呼叫目前類別的主建構函數。
而這個次建構函數,實例化時指輸入type,其他的都會套用它已經設好的初始值 : 顏色是黃色、續航力72小時。

fun main() {
    val robotCat = Robot("cat", "blue", 84)
    val robotDog = Robot("dog")

    println("robotCat :\ntype :${robotCat.type} , color: ${robotCat.color} , batteryLife : ${robotCat.batteryLife}hours")
    println("robotDog :\ntype :${robotDog.type} , color: ${robotDog.color}, batteryLife : ${robotDog.batteryLife}hours\"")
//運行結果:
// robotCat :
// type :cat , color: blue , batteryLife : 84hours
// robotDog :
// type :dog , color: yellow, batteryLife : 72hours"
}

初始化區塊

在類別中,以關鍵字init定義一個初始化區塊,指該類別實例一被建立就會執行的區塊。初始化區塊可以設定變數或值,以及執行有效性檢查...等。
一旦初始化區塊有一項不通過便會拋出IllegalArgumentException異常。
例如我們可以要求機器人type必須設置、檢查電池有沒有損壞,如下:

class Robot(
    val type: String,
    val color: String,
    val batteryLife: Int
) {
    //次建構函數:
    constructor(type: String) : this(type, color = "yellow", batteryLife = 72)
    
    //初始化區塊 : 檢查type屬性有無設定、batteryLife 不可小於等於0、沒問題就會印出字串
    init {
        require(type.isNotBlank(), { "type屬性必須設定" })
        require(batteryLife > 0, { "電池可能已損壞無法使用" })
        println("Initialize a new Robot object : type :$type ,color : $color , battery life : $batteryLife hours")
    }

    fun work() {...}
}

參考: kotlin文檔、權威2.0、第一行代碼Android


上一篇
第20天 Kotlin小學堂(9) : 集合
下一篇
第22天 Kotlin小學堂(11) : 繼承
系列文
新手向Android&Kotlin學習紀錄30天30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言