下标
类,结构体和枚举都能定义下标来快速访问集合,列表或序列里面的元素, 可以省略调用一些方法的麻烦, 而且同一个类型可以定义多个下标操作符.
- 下标语法:
subscript(index: Int) -> Int {
get {
// 返回对应值
}
set(newValue) {
// 设置对应值
}
}
//如果想设为readOnly, 可以去掉set或者和只读的运算属性类似:
subscript(index: Int) -> Int {
// 返回对应值
}
值得一提的是, subscript接受任意多的参数.
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
}
}
}
使用也很简单:
var matrix = Matrix(rows: 2, columns: 2)
matrix[0, 1] = 1.5 // 话说一开始我还以为是[0][1]
matrix[1, 0] = 3.2
还是很基础的, 算是新加入的运算符吧...具体细节参考官方文档
继承
由于Swift对于extension和protocol的强化, 直接导致整个编程思想的变化, 所以很多人呼吁说停止继承, 面向协议. 即使如此, 我们还是要看看Swift里面的继承有什么特别的地方, 毕竟还是有地方会需要的.
- 继承
和ObjC一样, 也是用冒号(:)来表示继承, 而且也是单继承, 顺带一提, 实现协议也是用冒号(:), 如果有多个用逗号(,)分开.
class SomeSubclass: SomeSuperclass {
// subclass definition goes here
}
和ObjC不同的是, Swift不需要所有类都继承自一个公共基础类(如NSObject或者NSProxy)
- 重载
与ObjC不同的是, 子类重载父类的属性或者方法都需要显式写明override, 否则编译器会报错;
重载方法,属性或下标后, 在子类访问父类的方法,属性或下标都需要用到super;
需要注意的是, 如果重载属性, 则要根据父类对属性的实现有所区分(显式或者隐式的set/get都算), 而不仅仅是写一个属性声明即可(这肯定是必要的, 毕竟不会重载一个属性而不对它做任何操作吧? 如果只是给个初值为什么不在init里面做呢?)
以存储属性为例子:
class Human {
var age: Int = 0
}
class Man : Human {
override var age: Int {
get {
return super.age // 不写super就会无限递归
}
set {
if (newValue >= 0 && newValue <= 150) {
super.age = newValue // 不写super就会无限递归
}
}
}
}
var man = Man()
man.age = 200
man.age // 打印0
总结起来如下:
如果是存储属性, 那么get, set都要显式写出. 除非只是监听
如果是运算属性, 父类显式实现了什么子类重载只能多不能少. 除非只是监听
- 重载属性监听
如上面所说的, 重载也可能只是监听, 所以不需要显式写出get或者set, 例如:
class Man : Human {
override var age: Int {
willSet {
}
didSet{
}
}
}
willSet和didSet不需要同时都写出.
- 阻止重载
如果你不想让别人重载你的方法, 属性或者下标, 就用final来修饰, 例如:
final func , final var, final class func, final subscript.
甚至于, 如果你整个类都不想让别人继承, 直接写上final class
差不多就这样, 细节参考官方文档