本文首發於我的博客html
同其餘語言同樣,Swift中也是有繼承的git
override
關鍵字Animal類
,其中Dog 類
繼承Animal類
,其中ErHa 類
繼承Dog類
class Animal {
var age = 0
}
class Dog : Animal {
var weight = 0
}
class ErHa : Dog {
var iq = 0
}
複製代碼
Animal類
的內存以下代碼查看類的內存大小和相應內存的值,須要用到工具Mems 關於的使用能夠看Swift之枚舉一文,或者直接看github上Mems的說明github
let a = Animal()
a.age = 5
print(Mems.size(ofRef: a))
print(Mems.memStr(ofRef: a))
複製代碼
Animal類
的內存大小和內容,分別爲編程
32
0x00000001000084d8 //存放類的相關信息
0x0000000000000002 //引用技術
0x0000000000000005 // age數值5
0x0000000000000000 //沒用到
複製代碼
Animal類
的內存分析Dog類
的內存以下代碼查看類的內存大小和相應內存的值bash
let d = Dog()
d.age = 6
d.weight = 7
print(Mems.size(ofRef: d))
print(Mems.memStr(ofRef: d))
複製代碼
Dog類
的內存大小和內容,分別爲app
32
0x0000000100008588 //存放類的相關信息
0x0000000000000002 //引用技術
0x0000000000000006 // age數值6
0x0000000000000007 //weight的值7
複製代碼
Dog類
的內存分析ErHa類
的內存以下代碼查看類的內存大小和相應內存的值ide
let e = ErHa()
e.age = 8
e.weight = 9
e.iq = 10
print(Mems.size(ofRef: e))
print(Mems.memStr(ofRef: e))
複製代碼
ErHa類
的內存大小和內容,分別爲工具
48
0x0000000100008658 //存放類的相關信息
0x0000000000000002 //引用技術
0x0000000000000008 // age數值8
0x0000000000000009 //weight的值9
0x000000000000000a //iq的值10
0x0000000000000000 //內存對齊增長的,沒用到
複製代碼
ErHa類
的內存分析子類能夠重寫父類的實例方法、下標post
有個Animal
類ui
class Animal {
func speak() {
print("Animal speak")
}
subscript(index: Int) -> Int {
return index
}
}
複製代碼
子類Cat
繼承Animal
,若是重寫示例方法,下標,必須用關鍵字override
class Animal {
func speak() {
print("Animal speak")
}
subscript(index: Int) -> Int {
return index
}
}
class Cat : Animal {
override func speak() {
super.speak()
print("Cat speak")
}
override subscript(index: Int) -> Int {
return super[index] + 1
}
}
複製代碼
上面的實例方法、下標。若是是類型方法、下標的話,有些許不一樣,
eg
class Animal {
//static修飾
static func speak() {
print("Animal speak")
}
// class修飾
class subscript(index: Int) -> Int {
return index
}
}
print(Animal[6])
class Cat : Animal {
//編譯報錯 Cannot override static method
override class func speak() {
super.speak()
print("Cat speak")
}
//編譯成功
override class subscript(index: Int) -> Int {
return super[index] + 1
}
}
複製代碼
如上面的代碼所示static
修飾的時候,子類重寫,直接報錯Cannot override static method
。而class
修飾時候,編譯正常
重寫類型屬性,比較簡單,不作贅述
注意的是:若是子類把父類的存儲屬性int 重寫爲計算屬性,子類中依然有8個字節存儲該int屬性
再次須要注意的是,和重寫類型方法、下標相似 若是重寫類型屬性
eg,子類SubCircle
給父類Circle
的存儲屬性radius
增長屬性觀察器
class Circle {
var radius: Int = 1
}
class SubCircle : Circle {
override var radius: Int {
willSet {
print("SubCircle willSetRadius", newValue)
}
didSet {
print("SubCircle didSetRadius", oldValue, radius)
}
}
}
複製代碼
注意點:子類增長屬性觀察器以後,依然是存儲屬性
eg:
class Circle {
var radius: Int = 1 {
willSet {
print("Circle willSetRadius", newValue)
}
didSet {
print("Circle didSetRadius", oldValue, radius)
}
}
}
class SubCircle : Circle {
override var radius: Int {
willSet {
print("SubCircle willSetRadius", newValue)
}
didSet {
print("SubCircle didSetRadius", oldValue, radius)
}
}
}
var circle = SubCircle()
複製代碼
輸出爲
SubCircle willSetRadius 10
Circle willSetRadius 10
Circle didSetRadius 1 10
SubCircle didSetRadius 1 10
複製代碼
以下代碼
class Circle {
var radius: Int {
set {
print("Circle setRadius", newValue)
}
get {
print("Circle getRadius")
return 20
}
}
}
class SubCircle : Circle {
override var radius: Int {
willSet {
print("SubCircle willSetRadius", newValue)
}
didSet {
print("SubCircle didSetRadius", oldValue, radius)
}
}
}
複製代碼
使用
var circle = SubCircle()
circle.radius = 10
複製代碼
輸出結果爲
Circle getRadius
SubCircle willSetRadius 10
Circle setRadius 10
Circle getRadius
SubCircle didSetRadius 20 20
複製代碼
輸出結果分析
circle.radius = 10
的時候,先獲取了oldValue
,調用父類的get
輸出Circle getRadius
willSetRadius
準備賦值setRadius
print("SubCircle didSetRadius", oldValue, radius)
以前,要先獲取radius
的值,因此,須要先執行父類的getRadius
didSet
方法參考資料: