下標(biāo)
類,結(jié)構(gòu)體和枚舉都能定義下標(biāo)來快速訪問集合,列表或序列里面的元素, 可以省略調(diào)用一些方法的麻煩, 而且同一個(gè)類型可以定義多個(gè)下標(biāo)操作符.
- 下標(biāo)語(yǔ)法:
subscript(index: Int) -> Int {
get {
// 返回對(duì)應(yīng)值
}
set(newValue) {
// 設(shè)置對(duì)應(yīng)值
}
}
//如果想設(shè)為readOnly, 可以去掉set或者和只讀的運(yùn)算屬性類似:
subscript(index: Int) -> Int {
// 返回對(duì)應(yīng)值
}
值得一提的是, subscript接受任意多的參數(shù).
struct Matrix {
let rows: Int, columns: Int
var grid: [Double]
init(rows: Int, columns: Int) {
self.rows = rows
self.columns = columns
grid = Array(count: rows * columns, repeatedValue: 0.0)
}
func indexIsValidForRow(row: Int, column: Int) -> Bool {
return row >= 0 && row < rows && column >= 0 && column < columns
}
subscript(row: Int, column: Int) -> Double {
get {
assert(indexIsValidForRow(row, column: column), "Index out of range")
return grid[(row * columns) + column]
}
set {
assert(indexIsValidForRow(row, column: column), "Index out of range")
grid[(row * columns) + column] = newValue
}
}
}
使用也很簡(jiǎn)單:
var matrix = Matrix(rows: 2, columns: 2)
matrix[0, 1] = 1.5 // 話說一開始我還以為是[0][1]
matrix[1, 0] = 3.2
還是很基礎(chǔ)的, 算是新加入的運(yùn)算符吧...具體細(xì)節(jié)參考官方文檔
繼承
由于Swift對(duì)于extension和protocol的強(qiáng)化, 直接導(dǎo)致整個(gè)編程思想的變化, 所以很多人呼吁說停止繼承, 面向協(xié)議. 即使如此, 我們還是要看看Swift里面的繼承有什么特別的地方, 畢竟還是有地方會(huì)需要的.
- 繼承
和ObjC一樣, 也是用冒號(hào)(:)來表示繼承, 而且也是單繼承, 順帶一提, 實(shí)現(xiàn)協(xié)議也是用冒號(hào)(:), 如果有多個(gè)用逗號(hào)(,)分開.
class SomeSubclass: SomeSuperclass {
// subclass definition goes here
}
和ObjC不同的是, Swift不需要所有類都繼承自一個(gè)公共基礎(chǔ)類(如NSObject或者NSProxy)
- 重載
與ObjC不同的是, 子類重載父類的屬性或者方法都需要顯式寫明override, 否則編譯器會(huì)報(bào)錯(cuò);
重載方法,屬性或下標(biāo)后, 在子類訪問父類的方法,屬性或下標(biāo)都需要用到super;
需要注意的是, 如果重載屬性, 則要根據(jù)父類對(duì)屬性的實(shí)現(xiàn)有所區(qū)分(顯式或者隱式的set/get都算), 而不僅僅是寫一個(gè)屬性聲明即可(這肯定是必要的, 畢竟不會(huì)重載一個(gè)屬性而不對(duì)它做任何操作吧? 如果只是給個(gè)初值為什么不在init里面做呢?)
以存儲(chǔ)屬性為例子:
class Human {
var age: Int = 0
}
class Man : Human {
override var age: Int {
get {
return super.age // 不寫super就會(huì)無限遞歸
}
set {
if (newValue >= 0 && newValue <= 150) {
super.age = newValue // 不寫super就會(huì)無限遞歸
}
}
}
}
var man = Man()
man.age = 200
man.age // 打印0
總結(jié)起來如下:
如果是存儲(chǔ)屬性, 那么get, set都要顯式寫出. 除非只是監(jiān)聽
如果是運(yùn)算屬性, 父類顯式實(shí)現(xiàn)了什么子類重載只能多不能少. 除非只是監(jiān)聽
- 重載屬性監(jiān)聽
如上面所說的, 重載也可能只是監(jiān)聽, 所以不需要顯式寫出get或者set, 例如:
class Man : Human {
override var age: Int {
willSet {
}
didSet{
}
}
}
willSet和didSet不需要同時(shí)都寫出.
- 阻止重載
如果你不想讓別人重載你的方法, 屬性或者下標(biāo), 就用final來修飾, 例如:
final func , final var, final class func, final subscript.
甚至于, 如果你整個(gè)類都不想讓別人繼承, 直接寫上final class
差不多就這樣, 細(xì)節(jié)參考官方文檔