iT邦幫忙

第 12 屆 iThome 鐵人賽

DAY 20
0
Software Development

給我 30 天,給你一輩子:Swift 從零開始系列 第 20

Day 20 | Swift Class 與 Struct 快樂二選一:Class 篇

  • 分享至 

  • xImage
  •  

Class 類別

Class 是什麼啊?是班級的意思嗎?
它可以用來做什麼呢?


Class 與 Object

在介紹 Class 之前,我想先來聊聊什麼是 Class 和 Obeject。

Class 不是班級的意思,在物件導向的概念裡,這通常被稱為類別。

物件導向程式設計Object-oriented programming ),有人把它稱作為 OOP 或是 OO,是一種具有物件設計概念的程式設計規則。

兩個概念:類別物件
三大特性:封裝繼承多型 (之後會再提到,今天先介紹類別跟物件)

  • 汽車,大家對於汽車的第一印象可能都不太一樣,可能每個人描述出來的汽車都有屬於自己的風格
  • 每台汽車都擁有自己獨特的一些特徵,例如:顏色、配備、性能或是輪子種類等,這些特徵可以被稱為這台汽車的屬性
  • 然而這些汽車的屬性的集合就可以構成一台車

我們來統整一下上述的案例,對於汽車來說它擁有一些汽車屬性,就好比設計一台汽車的藍圖,然而這個汽車的藍圖就可以稱做是一個類別

依照這個汽車的類別,實際上產出的汽車,不盡相同,那這個實際產出的汽車,就可以稱作是一個物件,針對這個實際產出的汽車,我們又把它稱作為實體( Instance )。

Class 宣告

class 類別名稱 {
    ...
}

類別命名需要符合幾個要素:

  • 類別名稱需遵從 Upper Camel Case,像是 SuperCar 或 SomeClass ...
  • 屬性方法命名以 Lower Camel Case,像是 carColor 或是 carWheel ...

Class 特性

這邊提到了屬性及方法,讓我們來介紹 Class 能做的一些基本功能:

  • 定義屬性
  • 定義方法
  • 定義初始值

屬性

在類別中的屬性沒特別定義的話幾乎都是 stored property,以用來存取。

class Car {
    var color = "White"
    var brand = "Lexus"
    var wheelSize = 19
}

車子類別中有 colorbrand 以及 wheelSize 屬性,如果想調用這些屬性,可以用兩種方式來調用:

  • 建立實體
  • 直接使用類別本身
// 建立 Instance
let car = Car()
print(car.color) // White

// 直接使用 class
print(Car().color) // White

當然你也可以修改屬性的值:

let car = Car()
print(car.color) // White

car.color = "Red"
print(car.color) // Red

方法

物件的方法,就是前幾章教的 Functions,只是被放到類別中。

class Car {
    var color = "White"
    var brand = "Lexus"
    var wheelSize = 19
    
    func engineStart() {
        print("拉風 引擎發動!")
    }
}

使用方式跟屬性的調用一樣,建立實體或是直接使用類別本身呼叫:

let car = Car()
car.engineStart()

Car().engineStart()

類別初始化

物件的屬性除了可以在類別中就先指派初始值,但他也可以不用先指派初始值,可以透過類別初始化的過程再來指派數值。

  • Designated Initializer:自定義建構器
  • Convenience Initializer:便利建構器

Designated Initializer 是 Class 最常用的初始化方式,我們來看語法:

init(參數列) {
	...
}

透過 init() 來完成類別本身的所有屬性初始化,所以在參數列就必須列出對應每個屬性的參數輸入。

class Car {
    var color: String
    var brand: String
    var wheelSize: Int
    
    init(color: String, brand: String, wheelSize: Int) {
        self.color = color
        self.brand = brand
        self.wheelSize = wheelSize
    }
    
    func engineStart() {
        print("拉風 引擎發動!")
    }
}

我們在宣告物件屬性時,只先註記了型別,但是沒指派初始值,透過 init() 來自定義建構式,帶入所需要設定的參數,上面例子有三個屬性需要被初始化,初始化的過程,會把三個輸入參數值指派給 self.屬性,self 代表著類別本身,就是 Car(),所以 self.屬性,就是 Car 類別的某一個類別。

透過自定義建構式的方式,就可以在建立實體的時候自訂車子的屬性:

let car = Car(color: "Black", brand: "Benz", wheelSize: 20)
print(car.color) // Black
print(car.brand) // Benz
print(car.wheelSize) // 20

但是如果我們只想要某些屬性透過自定義的方式,但有些想先設定初始值,那該怎麼做呢?

對於某些情況,我們不想要全部的屬性都透過自訂的方式來加入,我們希望在建立實體物件的時候,能夠只輸入部分的參數,其餘就採預設,這時候就可以透過 Convenience Initializer

根據蘋果官方文件,針對 Designated InitializerConvenience Initializer 有提到三項規則,第三條: Convenience Initializer 最後必須呼叫 Designated Initializer,我們來看一下語法:

convenience init(部分參數列) {
	self.init(參數列)
}

便利建構使用 convenience 作為關鍵字,後面是使用 init(),裡面的參數代表著你想要傳入的參數有哪些,

然而程式區塊裡面要做的是呼叫 self.init(),在帶入參數傳入以及你想先預設初始值的參數。

class Car {
    var color: String
    var brand: String
    var wheelSize: Int
    
    init(color: String, brand: String, wheelSize: Int) {
        self.color = color
        self.brand = brand
        self.wheelSize = wheelSize
    }
    
    convenience init(color: String, wheelSize: Int) {
        self.init(color: color, brand: "BMW", wheelSize: wheelSize)
    }
    
    func engineStart() {
        print("拉風 引擎發動!")
    }
}

我們使用 Convenience Initializer 來設定 brand 初始值為 BMW,所以我們來建立兩個 Instance 對比一下:

let car1 = Car(color: "Black", brand: "Benz", wheelSize: 20)
let car2 = Car(color: "Black", wheelSize: 20)

print(car1.color, car1.brand, car1.wheelSize)
print(car2.color, car2.brand, car2.wheelSize)

/*
Prints:
Black Benz 20
Black BMW 20
*/

car2 這個實體在建構的時候,省略了 brand 所以這時候就會呼叫 Convenience Initializer 來取得 brand 的初始值 BMW


今天這篇先介紹到這邊,接下來會再介紹與 Class 很相似的 Struct,並且解析他們的差異是什麼,該如何選擇即使用。/images/emoticon/emoticon29.gif


上一篇
Day 19 | Swift Enumerations
下一篇
Day 21 | Swift Class 與 Struct 快樂二選一:Struct 篇
系列文
給我 30 天,給你一輩子:Swift 從零開始30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言