溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊(cè)×
其他方式登錄
點(diǎn)擊 登錄注冊(cè) 即表示同意《億速云用戶服務(wù)條款》

23.swift繼承

發(fā)布時(shí)間:2020-08-01 04:38:41 來源:網(wǎng)絡(luò) 閱讀:442 作者:光光ing 欄目:移動(dòng)開發(fā)

import Foundation


/*

繼承語法

繼承是面向?qū)ο笞铒@著的一個(gè)特性, 繼承是從已經(jīng)有的類中派生出新的類

新的類能夠繼承已有類的屬性和方法, 并能擴(kuò)展新的能力

術(shù)語: 基類(父類, 超類), 派生類(子類, 繼承類)

語法:

 class 子類: 父類{

}


繼承有點(diǎn): 代碼重用

繼承缺點(diǎn): 增加程序耦合度, 父類改變會(huì)影響子類

注意:SwiftOC一樣沒有多繼承

*/


class Man {

    var name:String = "lnj"

    var age: Int = 30

    func sleep(){

        print("睡覺")

    }

}


class SuperMan: Man {

    var power:Int = 100

    func fly(){

        // 子類可以繼承父類的屬性

        print(" \(name) \(age)")

    }

}

var m = Man()

m.sleep()

//m.fly() // 父類不可以使用子類的方法


var sm = SuperMan()

sm.sleep()// 子類可以繼承父類的方法

sm.fly()



/*

super關(guān)鍵字:

 

派生類中可以通過super關(guān)鍵字來引用父類的屬性和方法

*/


class Man2 {

    var name:String = "lnj"

    var age: Int = 30

    func sleep(){

        print("睡覺")

    }

}


class SuperMan2: Man2 {

    var power:Int = 100

    func eat()

    {

        print("吃飯")

    }

    func fly(){

        // 子類可以繼承父類的屬性

        print(" \(super.name) \(super.age)")

    }

    func eatAndSleep()

    {

        eat()

        super.sleep()

        // 如果沒有寫super, 那么會(huì)現(xiàn)在當(dāng)前類中查找, 如果找不到再去父類中查找

        // 如果寫了super, 會(huì)直接去父類中查找

    }

}

var sm2 = SuperMan2()

sm2.eatAndSleep()


/*

方法重寫: override

重寫父類方法, 必須加上override關(guān)鍵字

*/


class Man3 {

    var name:String = "lnj"

    var age: Int = 30

    func sleep(){

        print("睡覺")

    }

}


class SuperMan3: Man3 {

    var power:Int = 100

    // override關(guān)鍵字主要是為了明確表示重寫父類方法

    // 所以如果要重寫父類方法, 必須加上override關(guān)鍵字

    override func sleep() {

//        sleep() // 不能這樣寫, 會(huì)導(dǎo)致遞歸

        super.sleep()

        print("子類睡覺")

    }

    func eat()

    {

        print("吃飯")

    }

    func fly(){

        // 子類可以繼承父類的屬性

        print(" \(super.name) \(super.age)")

    }

    func eatAndSleep()

    {

        eat()

        sleep()

    }


}

var sm3 = SuperMan3()

// 通過子類調(diào)用, 優(yōu)先調(diào)用子類重寫的方法

//sm3.sleep()

sm3.eatAndSleep()



/*

重寫屬性

無論是存儲(chǔ)屬性還是計(jì)算屬性, 都只能重寫為計(jì)算屬性

*/


class Man4 {

    var name:String = "lnj" // 存儲(chǔ)屬性

    var age: Int { // 計(jì)算屬性

        get{

            return 30

        }

        set{

            print("man new age \(newValue)")

        }

    }

    func sleep(){

        print("睡覺")

    }

}

class SuperMan4: Man4 {

    var power:Int = 100

    // 可以將父類的存儲(chǔ)屬性重寫為計(jì)算屬性

    // 但不可以將父類的存儲(chǔ)屬性又重寫為存儲(chǔ)屬性, 因?yàn)檫@樣沒有意義

//    override var name:String = "zs"

    override var name:String{

        get{

            return "zs"

        }

        set{

            print("SuperMan new name \(newValue)")

        }

    }

    // 可以將父類的計(jì)算屬性重寫為計(jì)算屬性, 同樣不能重寫為存儲(chǔ)屬性

    override var age: Int { // 計(jì)算屬性

        get{

            return 30

        }

        set{

            print("superMan new age \(newValue)")

        }

    }

}

let sm4 = SuperMan4()

// 通過子類對(duì)象來調(diào)用重寫的屬性或者方法, 肯定會(huì)調(diào)用子類中重寫的版本

sm4.name = "xxx"

sm4.age = 50



/*

重寫屬性的限制

1.讀寫計(jì)算屬性/存儲(chǔ)屬性, 是否可以重寫為只讀計(jì)算屬性? (權(quán)限變小)不可以

2.只讀計(jì)算屬性, 是否可以在重寫時(shí)變成讀寫計(jì)算屬性? (權(quán)限變大)可以

3.只需

*/

class Man5 {

    var name:String = "lnj" // 存儲(chǔ)屬性

    var age: Int { // 計(jì)算屬性

        get{

            return 30

        }

        set{

            print("man new age \(newValue)")

        }

    }

    func sleep(){

        print("睡覺")

    }

}

class SuperMan5: Man5 {

    var power:Int = 100

    override var name:String{

        get{

            return "zs"

        }

        set{

            print("SuperMan new name \(newValue)")

        }

    }

    override var age: Int { // 計(jì)算屬性

        get{

            return 30

        }

        set{

            print("superMan new age \(newValue)")

        }

    }

}




/*

重寫屬性觀察器

只能給非lazy屬性的變量存儲(chǔ)屬性設(shè)定屬性觀察器

不能給計(jì)算屬性設(shè)置屬性觀察器,給計(jì)算屬性設(shè)置屬性觀察器沒有意義

屬性觀察器限制:

    1.不能在子類中重寫父類只讀的存儲(chǔ)屬性

    2.不能給lazy的屬性設(shè)置屬性觀察器

*/


class Man6 {

    var name: String = "lnj"

    var age: Int = 0 { // 存儲(chǔ)屬性

        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 SuperMan6: Man6 {

    // 可以在子類中重寫父類的存儲(chǔ)屬性為屬性觀察器

    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)")

        }


    }

    // 可以在子類重寫父類的計(jì)算屬性為屬性觀察器

    override var height:Double{

        willSet{

            print("child height")

        }

        didSet{

            print("child height")

        }

    }

}


var m6 = SuperMan6()

//m6.age = 55

//print(m.age)

m6.height = 20.0



/*

利用final關(guān)鍵字防止重寫

final關(guān)鍵字既可以修飾屬性, 也可以修飾方法, 并且還可以修飾類

final關(guān)鍵字修飾的屬性和方法不能被重寫

final關(guān)鍵字修飾的類不能被繼承

*/

final class Man7 {

    final var name: String = "lnj"

    final var age: Int = 0 { // 存儲(chǔ)屬性

        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("吃飯")

    }

}


向AI問一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI