继承

类可以继承父类的方法、属性和其他特征

swift中,类可以调用和访问超类的方法,属性和下标,并且可以重写这些方法、属性和下标来优化或修改它们的行为。Swift会检查你的重写定义在超类中是够有匹配的定义,确保重写行为的正确

可以为类中继承的属性添加属性观察器,来检查属性改变。可以为任何属性添加属性观察期,无论原来被定为存储属性还是计算属性

定义一个基类

不继承于其它类的类,称之为基类

注意:

Swift中类并不是从一个通用类继承而来.如果没有为定义的类制定一个超类的话,这个类自动成为一个基类

创建一个Vehicle的基类,来描述通用车辆

class Vehicle {
    var currentSpeed = 0.0
    var description: String {
        return "traveling at \(currentSpeed) miles per hour"
    }
    func makeNoise() {
        // 什么也不做-因为车辆不一定会有噪音
    }
}

子类生成

//定义一个自行车Bicycle继承自Vehicle
class Bicycle: Vehicle {
    var hasBasket = false
}

除了继承自父类的方法、属性外,还定义了一个默认值为false的存储属性hasBasket

let bicycle = Bicycle()
bicycle.hasBasket = true
//修改继承的属性
bicycle.currentSpeed = 15.0
print("Bicycle: \(bicycle.description)")
// 打印 "Bicycle: traveling at 15.0 miles per hour"

重写

为继承来的实例方法、类方法、实例属性、下标提供自己的实现,即为重写

通过在在重写定义前加上 override关键字表明重写,否则即为错误的提供了相同的定义

任何缺少override关键字的的重写都会在编译时被认为错误

访问父类的方法、属性和下标

通过super前缀来访问父类版本中的方法、属性或下标

  • 在方法 someMethod() 的重写实现中,可以通过 super.someMethod() 来调用超类版本的 someMethod() 方法
  • 在属性 someProperty 的 getter 或 setter 的重写实现中,可以通过 super.someProperty 来访问超类版本的someProperty 属性
  • 在下标的重写实现中,可以通过 super[someIndex] 来访问超类版本中的相同下标

重写方法

class Train: Vehicle {
    override func makeNoise() {
        print("Choo Choo")
    }
}

重写属性

重写继承来的实例或者类型属性,提供自己定制的getter或者setter,或添加属性观察器来观察属性值的改变

重写属性的setter和getter

子类并不知道继承来的属性是存储型还是计算型,重写时要提供属性名称和类型来让编译器去查找父类同名同类型的属性

可以把继承的只读属性重写为可读写,但是没有办法把可读写的重写为只读属性

注意:

如果你在重写属性中提供了setter,那么你也一定要提供getter。如果你不想在重写版本中的
getter里修改继承来的属性值,你可以直接通过super.someProperty来返回继承来的值

class Car: Vehicle {
    var gear = 1
    //重写description属性
    override var description: String {
        return super.description + " in gear \(gear)"
    }
}

let car = Car()
car.currentSpeed = 25.0
car.gear = 3
print("Car: \(car.description)")//返回自定义描述
// 打印 "Car: traveling at 25.0 miles per hour in gear 3"

重写属性观察器

可以通过重写来为集成来的属性添加属性观察器。这样一来,无论被继承属性原本如何实现,当其属性值发生改变时,就会被通知到。

注意:

  1. 不能为继承来的常量存储型属性或继承来的只读计算型属性添加属性观察器,因为这些属性不能被设置的
  2. 不能同时提供重写的setter和重写的属性观察器。因为此时我们可以直接在setter中观察值的变化
class AutomaticCar: Car {
    override var currentSpeed: Double {
        didSet {
            gear = Int(currentSpeed / 10.0) + 1(后向下取得最接近的整数值在加1)
        }
    }
}

为属性currentSpeed添加观察器,设置速度时就会自动选择合适的档位

防止重写

通过把方法、属性或下标 前加关键字final关键字就可以来防止被重写,例如:final varfinal funcfinal class func ,以及 final subscript

任何试图对finial标记的方法、属性或下标进行重写的代码,都会在编译时报错。

在类扩展中的方法、属性或下标也可以在扩展的定义中标记finial

通过在关键字class前添加关键字final表示这个类是不可被继承的