Swift学习笔记(六)--下标与继承

下标

类,结构体和枚举都能定义下标来快速访问集合,列表或序列里面的元素, 可以省略调用一些方法的麻烦, 而且同一个类型可以定义多个下标操作符.

  1. 下标语法:
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里面的继承有什么特别的地方, 毕竟还是有地方会需要的.

  1. 继承
    和ObjC一样, 也是用冒号(:)来表示继承, 而且也是单继承, 顺带一提, 实现协议也是用冒号(:), 如果有多个用逗号(,)分开.
class SomeSubclass: SomeSuperclass {
    // subclass definition goes here
}

和ObjC不同的是, Swift不需要所有类都继承自一个公共基础类(如NSObject或者NSProxy)

  1. 重载
    与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都要显式写出. 除非只是监听
如果是运算属性, 父类显式实现了什么子类重载只能多不能少. 除非只是监听

  1. 重载属性监听
    如上面所说的, 重载也可能只是监听, 所以不需要显式写出get或者set, 例如:
class Man : Human {
     override var age: Int {
       willSet {
     
       }
      didSet{
  
      }
    }
}

willSet和didSet不需要同时都写出.

  1. 阻止重载
    如果你不想让别人重载你的方法, 属性或者下标, 就用final来修饰, 例如:
    final func , final var, final class func, final subscript.
    甚至于, 如果你整个类都不想让别人继承, 直接写上final class

差不多就这样, 细节参考官方文档

你可能感兴趣的:(Swift学习笔记(六)--下标与继承)