//感觉继承和oc的继承差不多
//继承
// “一个类可以继承另一个类的方法,属性和其它特性。当一个类继承其它类时,继承类叫子类,被继承类叫超类(或父类)。在 Swift 中,继承是区分「类」与其它类型的一个基本特征。”
//“类可以调用和访问超类的方法,属性和下标,并且可以重写这些方法,属性和下标来优化或修改它们的行为。Swift 会检查你的重写定义在超类中是否有匹配的定义,以此确保你的重写行为是正确的。”
//“可以为类中继承来的属性添加属性观察器,这样一来,当属性值改变时,类就会被通知到。可以为任何属性添加属性观察器,无论它原本被定义为存储型属性还是计算型属性”
//1. 定义一个基类
//“Swift 中的类并不是从一个通用的基类继承而来。如果你不为你定义的类指定一个超类的话,这个类就自动成为基类。”
class Vehicle{
var currentSpeed = 0.0
var description:String {
return "traveling at \(currentSpeed) miles per hour"
}
func makeNoise() {
//什么也不做
}
}
let someVehicle = Vehicle()
print("Vehicle:\(someVehicle.description)")
//2.子类生成
//“子类生成指的是在一个已有类的基础上创建一个新的类。子类继承超类的特性,并且可以进一步完善。你还可以为子类添加新的特性。为了指明某个类的超类,将超类名写在子类名的后面,用冒号分隔”
class Bicycle : Vehicle{
var hasBasket = false
}
//“新的Bicycle类自动获得Vehicle类的所有特性,比如currentSpeed和description属性,还有它的makeNoise()方法。除了它所继承的特性,Bicycle类还定义了一个默认值为false的存储型属性hasBasket(属性推断为Bool)”
let bicycle = Bicycle()
bicycle.hasBasket = true
bicycle.currentSpeed = 15.0
print("Bicycle:\(bicycle.description)")
//3.重写
//“子类可以为继承来的实例方法,类方法,实例属性,或下标提供自己定制的实现”
//“如果要重写某个特性,你需要在重写定义的前面加上override关键字。这么做,你就表明了你是想提供一个重写版本,而非错误地提供了一个相同的定义。意外的重写行为可能会导致不可预知的错误,任何缺少override关键字的重写都会在编译时被诊断为错误。”
//“override关键字会提醒 Swift 编译器去检查该类的超类(或其中一个父类)是否有匹配重写版本的声明。这个检查可以确保你的重写定义是正确的。”
//3.1 访问超类的方法,属性以及下标
//“当你在子类中重写超类的方法,属性或下标时,有时在你的重写版本中使用已经存在的超类实现会大有裨益。比如,你可以完善已有实现的行为,或在一个继承来的变量中存储一个修改过的值,在合适的地方,你可以通过使用super前缀来访问超类版本的方法,属性或下标”
/*
“在方法someMethod()的重写实现中,可以通过super.someMethod()来调用超类版本的someMethod()方法。
在属性someProperty的 getter 或 setter 的重写实现中,可以通过super.someProperty来访问超类版本的someProperty属性。
在下标的重写实现中,可以通过super[someIndex]来访问超类版本中的相同下标。”
*/
//3.2 重写方法
class Train: Vehicle{
override func makeNoise() {
print("Choo Choo")
}
}
let train = Train()
train.makeNoise()
//打印 Choo Choo
//3.3 重写属性的setter和getter
//“你可以重写继承来的实例属性或类型属性,提供自己定制的 getter 和 setter,或添加属性观察器使重写的属性可以观察属性值什么时候发生改变。”
//“你可以提供定制的 getter(或 setter)来重写任意继承来的属性,无论继承来的属性是存储型的还是计算型的属性。子类并不知道继承来的属性是存储型的还是计算型的,它只知道继承来的属性会有一个名字和类型。你在重写一个属性时,必需将它的名字和类型都写出来。这样才能使编译器去检查你重写的属性是与超类中同名同类型的属性相匹配的”
//“你可以将一个继承来的只读属性重写为一个读写属性,只需要在重写版本的属性里提供 getter 和 setter 即可。但是,你不可以将一个继承来的读写属性重写为一个只读属性。”
class Car:Vehicle{
var gear = 1
override var description: String{
return super.description + " in gear \(gear)"
}
}
// “重写的description属性首先要调用super.description返回Vehicle类的description属性。之后,Car类版本的description在末尾增加了一些额外的文本来提供关于当前档位的信息。”
let car = Car()
car.currentSpeed = 25.0
car.gear = 3
print("Car : \(car.description)")
//3.4 重写属性观察器
// “你可以通过重写属性为一个继承来的属性添加属性观察器。这样一来,当继承来的属性值发生改变时,你就会被通知到”
//注意: “你不可以为继承来的常量存储型属性或继承来的只读计算型属性添加属性观察器。这些属性的值是不可以被设置的,所以,为它们提供willSet或didSet实现是不恰当。”
//注意:“你不可以同时提供重写的 setter 和重写的属性观察器。如果你想观察属性值的变化,并且你已经为那个属性提供了定制的 setter,那么你在 setter 中就可以观察到任何值变化了”
class AutomaticCar:Car{
override var currentSpeed: Double{
didSet{
gear = Int(currentSpeed/10.0) + 1
}
}
}
//“当你设置AutomaticCar的currentSpeed属性,属性的didSet观察器就会自动地设置gear属性,为新的速度选择一个合适的挡位”
let automatic = AutomaticCar()
automatic.currentSpeed = 35.0
print("AutomaticCar:\(automatic.description)")
//打印 AutomaticCar:traveling at 35.0 miles per hour in gear 4
//4. 防止重写
//“你可以通过把方法,属性或下标标记为final来防止它们被重写,只需要在声明关键字前加上final修饰符即可(例如:final var,final func,final class func,以及final subscript)”
//“你可以通过在关键字class前添加final修饰符(final class)来将整个类标记为 final 的。这样的类是不可被继承的”