swift基礎語法(26-繼承,super關鍵字,override關鍵字,final關鍵字)


繼承語法
繼承是面向對象最顯著的一個特性, 繼承是從已經有的類中派生出新的類
新的類能夠繼承已有類的屬性和方法, 並能擴展新的能力
術語: 基類(父類, 超類), 派生類(子類, 繼承類)
語法:
 class 子類: 父類{
}
繼承優點: 代碼重用
繼承缺點: 增加程序耦合度, 父類改變會影響子類
注意:Swift和OC一樣沒有多繼承
class Man {
    var name:String = "qbs"
    var age: Int = 10
    func sleep(){
        print("睡覺")
    }
}
class SuperMan: Man {
    var power:Int = 100
     funs fly(){
        子類可以繼承父類的屬性
        print("飛 \(name) \(age)")
    }
}
var m = Man()
m.sleep()
父類不可以使用子類的方法
m.fly() 
輸出結果: 睡覺
var sm = SuperMan()
子類可以繼承父類的方法
sm.sleep()
sm.fly()
輸出結果:
睡覺
  qbs 10
 
 
super關鍵字:
派生類中可以通過super關鍵字來引用父類的屬性和方法
class Man {
    var name:String = "qbs"
    var age: Int = 30
    func sleep(){
        print("睡覺")
    }
}

class SuperMan: Man {
    var power:Int = 100
    func eat()
    {
        print("吃飯")
    }
    func fly(){
        子類可以繼承父類的屬性
        print("飛 \(super.name) \(super.age)")
    }
    func eatAndSleep()
    {
        eat()
        super.sleep()
        如果沒有寫super, 那么會先在當前類中查找, 如果找不到再去父類中查找
        如果寫了super, 會直接去父類中查找
    }
}
var sm = SuperMan()
sm.eatAndSleep()
輸出結果:
吃飯
睡覺
 
方法重寫: override
重寫父類方法, 必須加上override關鍵字
class Man {
    var name:String = "qbs"
    var age: Int = 10
    func sleep(){
        print("父類睡覺")
    }
}

class SuperMan: Man {
    var power:Int = 100
    override關鍵字主要是為了明確表示重寫父類方法,
    所以如果要重寫父類方法, 必須加上override關鍵字
    override func sleep() {
        sleep() 不能這樣寫, 會導致遞歸
        super.sleep()
        print("子類睡覺")
    }
    func eat()
    {
        print("吃飯")
    }
    func fly(){
        子類可以繼承父類的屬性
        print("飛 \(super.name) \(super.age)")
    }
    func eatAndSleep()
    {
        eat()
        sleep()
    }
   
}
var sm = SuperMan()
通過子類調用, 優先調用子類重寫的方法
sm.sleep()
輸出結果:
父類睡覺
子類睡覺
sm.eatAndSleep()
輸出結果:
吃飯
父類睡覺
子類睡覺
 
重寫屬性
無論是存儲屬性還是計算屬性, 都只能重寫為計算屬性
class Man {
    var name:String = "qbs"  存儲屬性
    var age: Int {  計算屬性
        get{
            return 30
        }
        set{
            print("man new age \(newValue)")
        }
    }
    func sleep(){
        print("睡覺")
    }
}

class SuperMan: Man {
    var power:Int = 100
     可以將父類的存儲屬性重寫為計算屬性
     但不可以將父類的存儲屬性又重寫為存儲屬性, 因為這樣沒有意義
     override var name:String = "zs"
    override var name:String{
        get{
            return "zs"
        }
        set{
            print("SuperMan new name \(newValue)")
        }
    }
 
    可以將父類的計算屬性重寫為計算屬性, 同樣不能重寫為存儲屬性
    override var age: Int { 計算屬性
        get{
            return 30
        }
        set{
            print("superMan new age \(newValue)")
        }
    }
}
let sm = SuperMan()
通過子類對象來調用重寫的屬性或者方法, 肯定會調用子類中重寫的版本
sm.name = "xxxoo"
sm.age = 50
輸出結果:
SuperMan new name xxxoo
superMan new age 50
 
 
重寫屬性的限制
1.讀寫計算屬性/存儲屬性, 是否可以重寫為只讀計算屬性? (權限變小)不可以
2.只讀計算屬性, 是否可以在重寫時變成讀寫計算屬性? (權限變大)可以
class Man {
    var name:String = "qbs"  存儲屬性
    var age: Int {  計算屬性
        get{
            return 30
        }
        set{
            print("man new age \(newValue)")
        }
    }
    func sleep(){
        print("睡覺")
    }
}
class SuperMan: Man {
    var power:Int = 100
    override var name:String{
        get{
            return "zs"
        }
        set{
            print("SuperMan new name \(newValue)")
        }
    }
    override var age: Int {  計算屬性
        get{
            return 30
        }
        set{
            print("superMan new age \(newValue)")
        }
    }
}
 
重寫屬性觀察器
只能給非lazy屬性的變量存儲屬性設定屬性觀察器,
不能給計算屬性設置屬性觀察器,給計算屬性設置屬性觀察器沒有意義
屬性觀察器限制:
    1.不能在子類中重寫父類只讀的存儲屬性
    2.不能給lazy的屬性設置屬性觀察器
 
class Man {
    var name: String = "qbs"
    var age: Int = 0 {  存儲屬性
        willSet{
            print("super new \(newValue)")
        }
        didSet{
            print("super new \(oldValue)")
        }
    }
    var height:Double{
        get{
            print("super get")
            return 10.0
        }
        set{
            print("super set")
        }
    }
}
class SuperMan: Man {
    可以在子類中重寫父類的存儲屬性為屬性觀察器
    override var name: String {
        willSet{
            print("new \(newValue)")
        }
        didSet{
            print("old \(oldValue)")
        }
    }
    可以在子類中重寫父類的屬性觀察器
    override var age: Int{
        willSet{
            print("child new \(newValue)")
        }
        didSet{
            print("child old \(oldValue)")
        }
       
    }
    可以在子類重寫父類的計算屬性為屬性觀察器
    override var height:Double{
        willSet{
            print("child height")
        }
        didSet{
            print("child height")
        }
    }
}
var m = SuperMan()
m.age = 55
輸出結果:
child new 55
super new 55
super new 0
child old 0
 
print(m.age)
輸出結果: 55
 
m.height = 20.0
輸出結果:
super get
child height
super set
child height
 
final關鍵字
利用final關鍵字防止重寫
final關鍵字既可以修飾屬性, 也可以修飾方法, 並且還可以修飾類
被final關鍵字修飾的屬性和方法不能被重寫
被final關鍵字修飾的類不能被繼承
 
final class Man {
    final var name: String = "qbs "
    final var age: Int = 0 { // 存儲屬性
        willSet{
            print("super new \(newValue)")
        }
        didSet{
            print("super new \(oldValue)")
        }
    }
    final var height:Double{
        get{
            print("super get")
            return 10.0
        }
        set{
            print("super set")
        }
    }
    final func eat(){
        print("吃飯")
    }
}
 
 
 
 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM