/**继承:一个类可以继承另一个类的方法、属性和其他特征。只有类才可以被继承。
可以为类中继承来的属性添加属性观察器,当属性值改变时,类就会被通知到。
*/
//=============================定义一个基类=============================
//不继承于其他类的类,称之为基类
class Vehicle { //车辆
var currentSpeed = 0.0
var description: String {
return "时速为:\(currentSpeed)"
}
func makeNoise() {//定义了一个名为 制造噪音 的方法,可供子类继承
print("父类 制造噪音的方法")
}
}
let someVehicle = Vehicle()
someVehicle.currentSpeed = 120.0
print("当前车辆:\(someVehicle.description)")
//=============================子类生成=============================
//子类生成:在一个已有类的基础上创建一个新的类,子类继承超类的特性,也可以为子类添加新的特性;
//为了指明某个类的超类,将超类名写在子类名的后面,用冒号分隔:
class Bicycle: Vehicle { //定义了一个名为Bicycle的子类,继承的超类为Vehicle
var hasBasket = false //该自行车默认没有篮子
}
let bicycle = Bicycle()
print("自行车的速度为:\(bicycle.currentSpeed),有无篮子:\(bicycle.hasBasket)")
bicycle.currentSpeed = 15.0 //修改父类属性
bicycle.hasBasket = true //修改自有属性
print("修改后==自行车的速度为:\(bicycle.description),有无篮子:\(bicycle.hasBasket)")
//子类还可以继续被其他类所继承
class Tandem: Bicycle { // 串联式自行车 (类Tandem继承了Bicycle)
var currentNumberOfPassengers = 0 //当前人数
}
let tandem = Tandem()
tandem.currentNumberOfPassengers = 3 //修改自己的属性
tandem.hasBasket = true // 修改父类的属性
tandem.currentSpeed = 12.0 // 修改 父类 的 父类 的属性
print("子类的子类:\(tandem.description)")
//=============================重写=============================
//重写:子类可以为继承来的实例方法、类方法、实例属性或下标 提供自己定制的实现。
//如果要重写某个特性,需要在重写定义的前面加上 override 关键字。这样就表明你想重写一个版本,而不是错误地提供了一个相同的定义。
//override关键字 会提醒Swift编译器去检查该类的超类 是否有匹配重写版本的声明,这个检查可以确保你的重写定义是正确的。
//1.通过使用super前缀 来访问 超类的方法、属性及下标
/*在方法someMethod()的重写实现中,可以通过super.someMethod()来调用超类版本的someMethod()方法。
在属性someProperty的 getter 或 setter 的重写实现中,可以通过super.someProperty来访问超类版本的someProperty属性。
在下标的重写实现中,可以通过super[someIndex]来访问超类版本中的相同下标。
*/
//2.重写方法
class Train: Vehicle { //火车 : 车辆
override func makeNoise() { //重写了父类 制造噪音的方法
print("火车的声音是:逛吃 逛吃 逛吃")
}
}
let train = Train()
train.makeNoise()//打印的是:火车的声音是:逛吃 逛吃 逛吃
//3.重写属性
//重写属性的getter 和 setter 方法:重写时,必须将属性的名字和类型都写出来。(子类并不知道继承来的属性是存储属性还是计算属性)
//可以将继承来的只读属性重写为读写属性,但不能将继承来的读写属性重写为只读属性 (可以扩充父类的属性功能,但不能减少父类的属性功能)
//如果你在重写属性中提供了setter,那么一定要提供getter;如果你不想重写getter,你可以直接通过 super.属性 来返回继承来的值
class Car: Vehicle { //汽车 : 车辆
var gear = 1 //档位
override var description: String { // 重写了父类的 description 属性,并改了他的值
return super.description + ",档位为:\(gear)档"
}
}
let car = Car()
car.currentSpeed = 60.0
car.gear = 4
print("汽车:\(car.description)")//汽车:时速为:60.0,档位为:4档
//4.重写属性观察器
//子类可以通过重写父类的属性,来添加属性观察器;当继承来的属性值改变是,会收到通知。
//注意1:不能给 继承来的常量存储属性 和 继承来的只读计算型属性 添加属性观察器,因为他们的值是不可以被设置的
//注意2:不能同时提供 重写属性的setter 和 重写的属性观察器,如果你想观察重写的属性值的变化,在setter中就可以观察到
class AutoMaticCar: Car { //自动挡汽车 : 汽车
override var currentSpeed: Double { //重写当前速度的属性;
didSet {//属性观察器将新的速度值除以10 再加一 就得到了档位
gear = Int(currentSpeed / 10.0) + 1 //自动挡汽车的档位为: 速度/10 + 1 ;每挡速度加10
}
}
}
let automatic = AutoMaticCar()
automatic.currentSpeed = 35.0
print("自动挡汽车:\(automatic.description)")//自动挡汽车:时速为:35.0,档位为:4档
//=============================防止重写=============================
/**防止重写: 可以把方法、属性、下标 标记为final来防止它们被重写,只需要在声明关键字前加上final修饰符即可。例如:
final var 、
final func、
final class func、
final subscript 等。
如果你重写了带有final标记的方法、属性、下标,在编译时会报错
在类扩展中的方法、属性、下标 也可以在扩展的定义里标记为final
也可以通过在关键字class前添加final修饰符(final class)来讲整个类 标记为final,使得该类不可被继承。试图继承该类会导致编译报错
*/
网友评论