继承
-
值类型(枚举、结构体)不支持继承,只有类(class)才能被继承;
- 没有父类的类,为基类;
- swift 中没有像oc一样,任何类最终必须继承某个基类(如NSObject);
- 子类继承父类的方法、下标、属性,如果重写父类的方法、下标、属性必须加上override关键字;
内存结构
- 可以看出实例对象在堆中存储结构为,前面16个字节保留(前8位是指向类型信息,后8位是引用计算);之后存储的是属性值,父类的属性值在前,子类的属性值在后;
- 由于类的内存存储大小为16个字节的倍数;所以图一的占用堆空间大小为32个字节,图二占用堆空间为48个字节;
重写实例方法、下标
class Animal {
func run() {
print("Animal run")
}
subscript(index: Int) -> Int {
return index
}
}
class Person: Animal {
override func run() {
super.run()
print("Person run")
}
override subscript(index: Int) -> Int {
return super[index] + 1
}
}
var p = Person()
/*
Animal run
Person run
*/
p.run()
// 11
print(p[10])
- 重写父类的方法、下标,需要加上 override 关键字;
- 使用 super 可以调用父类的方法、下标;
重写类型方法、下标
- 被class修饰的类型方法、下标,允许被子类重写;
- 被static修饰的类型方法、下标,不允许被子类重写;
class Animal {
class func run() {
print("Animal run")
}
}
class Person: Animal {
override class func run() {
super.run()
print("Person run")
}
}
重写属性
- 子类可以将父类的属性(存储、计算)重写为计算属性;
- 子类不可以将父类属性重写为存储属性;
- 只能重写 var 属性,不能重写 let 属性;
- 重写时,属性名 和 属性类型 要一致;
- 子类重写后的属性权限 不能小于 父类属性的权限;
- 被 class 修饰的 计算类型属性 ,可以被子类重写;
- 被 static 修饰的 类型属性(计算、存储) ,不可以被子类重写;
属性观察器
- 可以在子类中,为父类属性(除了只读计算属性、let属性)增加属性观察器;
- 可以在子类中,给父类的 计算属性 增加属性观察器;
class Animal {
class var age: Int {
set {
print("Animal set ",newValue)
}
get {
print("Animal get ")
return 10
}
}
}
class Person: Animal {
override class var age: Int {
willSet {
print("Person willSet ", newValue)
}
didSet {
print("Person didSet ", oldValue, age)
}
}
}
Person.age = 20
/*
Animal get
Person willSet 20
Animal set 20
Animal get
Person didSet 10 10
*/
final
- 被 final 修饰的方法、下标、属性,禁止 被 重写;
- 被 final 修饰的类,禁止 被 继承;