Class 是什麼啊?是班級的意思嗎?
它可以用來做什麼呢?
在介紹 Class 之前,我想先來聊聊什麼是 Class 和 Obeject。
Class 不是班級的意思,在物件導向的概念裡,這通常被稱為類別。
物件導向程式設計(
Object-oriented programming
),有人把它稱作為 OOP 或是 OO,是一種具有物件設計概念的程式設計規則。
兩個概念:
類別
及物件
三大特性:封裝
、繼承
及多型
(之後會再提到,今天先介紹類別跟物件)
我們來統整一下上述的案例,對於汽車來說它擁有一些汽車屬性,就好比設計一台汽車的藍圖,然而這個汽車的藍圖就可以稱做是一個類別
。
依照這個汽車的類別,實際上產出的汽車,不盡相同,那這個實際產出的汽車,就可以稱作是一個物件
,針對這個實際產出的汽車,我們又把它稱作為實體
( Instance )。
class 類別名稱 {
...
}
類別命名需要符合幾個要素:
類別名稱
需遵從 Upper Camel Case,像是 SuperCar 或 SomeClass ...屬性
或方法
命名以 Lower Camel Case,像是 carColor 或是 carWheel ...這邊提到了屬性及方法,讓我們來介紹 Class 能做的一些基本功能:
在類別中的屬性沒特別定義的話幾乎都是 stored property,以用來存取。
class Car {
var color = "White"
var brand = "Lexus"
var wheelSize = 19
}
車子類別中有 color
、brand
以及 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 Initializer
和 Convenience 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
,並且解析他們的差異是什麼,該如何選擇即使用。