继承
一个类可以继承另一个类的方法(methods),属性(properties)和其它特性。当一个类继承其它类时,继承类叫子类,被继承类叫超类(父类)。
在 Swift 中,子类可以调用和访问父类的方法,属性和下标脚本(subscripts),并且可以重写(override)这些方法、属性和下标脚本来优化或修改它们的行为。Swift 会检查你的重写定义在超类中是否有匹配的定义,以此确保你的重写行为是正确的。
可以为子类中继承来的属性添加属性观察器(property observers),这样一来,当属性值改变时,类就会被通知到。可以为任何属性添加属性观察器,无论它原本被定义为存储型属性(stored property)还是计算型属性(computed property)。
子类生成
class Vehicle{ // 当一个类不继承任何类 默认为基类 var currentSpeed = 0.0 var discription: String { return "traveling at (currentSpeed) miles per hour" } func makeNoise() { // do something } } // 上面的代码生成了一个交通工具的基类 下面来生成子类 class Bicycle: Vehicle { // 冒号后跟随父类的名字就可以继承父类 var hasBasket = false } // 先看下父类 let someVehicle = Vehicle() someVehicle.currentSpeed = 15.0 print("someVehicle: (someVehicle.discription)") // 打印出 : "someVehicle: traveling at 15.0 miles per hour " // 再看下子类 let someBicycle = Bicycle() someBicycle.currentSpeed = 20.0 someBicycle.hasBasket = true print("someBicycle: (someBicycle.discription)") // 打印出 : "someBicycle: traveling at 20.0 miles per hour " // 子类除了自己的属性外 还可以调用父类的属性和方法 这些就是继承的特性
重写
子类可以为继承来的实例方法(instance method),类方法(class method),实例属性(instance property),或下标脚本(subscript)提供自己定制的实现(implementation)。我们把这种行为叫重写(overriding)
重写方法
class Train: Vehicle { // 要想重写父类的特性时 在func前必须加上 override override func makeNoise() { print("ku ku ku ku ku...") } } let train = Train() train.makeNoise()
重写属性
注意:子类可以将父类的只读属性重写为读写属性,但是绝对不可以将父类的读写属性重写为只读属性。
class Car: Vehicle { var gear = 1 // 在基类中 discription是只读属性 但是在子类中可以重写这个属性并且增加setter方法 override var discription: String{ set { print(newValue) } get { return super.discription + "in the gear: (gear)" // super代表基类的意思 调用 super.discription 会返回一个字符串 然后将这个字符串拼接一些你想要的东西后 作为get返回 } } }
重写属性观察器
注意:你不可以为继承来的常量存储型属性或继承来的只读计算型属性添加属性观察器。这些属性的值是不可以被设置的,所以,为它们提供willSet
或didSet
实现是不恰当。此外还要注意,你不可以同时提供重写的 setter 和重写的属性观察器。如果你想观察属性值的变化,并且你已经为那个属性提供了定制的 setter,那么你在 setter 中就可以观察到任何值变化了。
class AutomaticCar: Car { override var currentSpeed: Double { didSet { gear = Int(currentSpeed / 10.0) + 1 } // 重写了currentSpeed 添加了属性观察期,这样当currentSpeed被赋值后可以做一些你想做的事情 } }
重写下标脚本
因为重写下标脚本与重写属性类似,所以就不多做介绍了
class someClass{ subscript(index: Int) -> Int { set { } get { return 0 } } } class subClass: someClass { override subscript(index: Int) -> Int { set { print(newValue) } get { return 100 } } }
防止重写
如果你声明了一个类,并且这个类有一些特性不想被重写,可以使用final关键字来防止重写
class Car: Vehicle { final var gear = 1 final func brake(){ gear = 0 currentSpeed = 0.0 } // 加上final关键字 如果有类继承这个类 也不会成功重写这些特性 }