Swift:物件導向(繼承與構造方法)

來源:互聯網
上載者:User

標籤:swift   屬性   方法   析構   

一、 繼承

1.  Swift中定義的類,如果不繼承自任何類,它就是基類。這一點和objective-c中定義的類不一樣,在objective-c中定義的類預設的基類是NSObject。
2.  重寫父類的方法及屬性,必須使用override的關鍵字(這樣處理的話,更清晰了,很容易看出是父類的方法還是自己類中的方法)。
3.  如果在類,方法,屬性 前面用final進行了修飾,就不允許被繼承或者被重寫。

類繼承關係Demo:

class Animal {        var speed : Int = 1        func run() {        println("Animal is running")    }}class Dog: Animal {        override var speed : Int {        get {            return super.speed        }        set {            if newValue > 100 {                super.speed = 100            } else {                super.speed = newValue            }        }    }        override func run() {        println("Dog is running")    }}

二、 構造方法

在Swift中,儲存屬性在定義的時候必須要進行初始化工作,這一點我在Swift:物件導向(屬性)中有提到過。如果不進行初始化的話,我們也可以在構造方法中完成初始化工作。

Swift中構造方法的特點:

1. 方法名字叫做init。

2. 沒有func關鍵字。

3. 沒有返回值。

Demo:

class Person {    var name: String    var age: Int        init(name: String , age: Int) {        self.name = name        self.age = age    }}var p = Person(name: "Rose", age: 30)

在本例中,有兩個儲存屬性name和age,它們在定義的時候均沒有完成初始化工作,但我們可以在init(name: String, age: Int) 這個構造方法中完成它們的初始化工作。self.name 和 self.age 就是定義的兩個屬性,而 name 和 age 就是外界傳遞過來的變數值。

三、 指定構造方法(Designated) 和 便利構造方法(Convenience)

關於指定構造方法和便利構造方法的使用有很多規則。

1. 只有便利構造方法才能調用當前類的其他構造方法。

class Person {    var name: String    var age: Int        init(name: String, age: Int) {        self.name = name        self.age = age    }        init(name: String) {        self.init(name: name, age: 10)    }}

在上例中,試圖在init(name: String) 這個構造方法中調用init(name: String, age: Int)這個構造方法,並且age的預設值是10。但是程式會直接報錯。


可以看出,錯誤資訊很明顯,提示你在init(name: String) 構造方法之前加上convenience, 使這個構造方法變成便利構造方法即可。

2. 只有指定構造方法才能調用父類的構造方法

class Person {    var name: String    var age: Int        init(name: String, age: Int) {        self.name = name        self.age = age    }        convenience init(name: String) {        self.init(name: name, age: 10)    }}class Jack: Person {    convenience init(name: String) {        super.init(name: name, age: 20)    }}

上例中,試圖在Jack這個子類的 convenience init(name: String) 這個便利構造方法中調用父類Person的指定構造方法init(name: String, age: Int)。但是程式會報錯。


所以,我們將Jack這個類中的convenience這個關鍵字去掉即可。讓子類的直接構造方法調用父類的直接構造方法。

3. 有參的指定構造方法會覆蓋調用預設的無參指定構造方法。

在Swift中定義的類中,都有一個預設的無參指定構造方法,只是沒有顯示出來。例如:

class Person {}

它其實有一個 init(){}  指定構造方法,這也是為什麼可以書寫下面的程式碼完成對象的初始化工作。

var p = Person()

但是,如果你在代碼中書寫了有參指定構造方法,那麼預設的無參指定構造方法將被覆蓋掉。例如:

class Person {    var name: String    var age: Int    init(name: String, age: Int) {        self.name = name        self.age = age    }}

此時你再調用
var p = Person()
這句代碼將直接報錯了。


但如果想不管調用無參構造方法還是有參構造方法都可以。那麼你將預設的指定都早方法寫出來即可。

class Person {    var name: String    var age: Int        init() {        self.name = "rose"        self.age = 20    }        init(name: String, age: Int) {        self.name = name        self.age = age    }}

此時你調用如下代碼,是完全可以的。

var p = Person()var p2 = Person(name: "tick", age: 20)
4. 如果父類中存在有參的指定構造方法,子類的指定構造方法不會自動調用父類無參的指定構造方法。

class Person {    var name: String    var age: Int        init(name: String, age: Int) {        self.name = name        self.age = age    }}class Jack: Person {    override init(name: String, age: Int) {        super.init()    }}

子類Jack的構造方法調用了父類的init預設無參的構造方法,將會直接報錯。


所以我們在子類的構造方法中可直接調用父類的有參構造方法即可,代碼如下:

super.init(name: name, age: age)

5. 常量屬性只能在定義它的類的構造方法中初始化,不能在子類中初始化。

class Person {    var name: String    var age: Int    let gender: String        init(name: String, age: Int, gender: String) {        self.name = name        self.age = age        self.gender = gender    }}class Jack: Person {    override init(name: String, age: Int, gender: String) {        self.age = 10        self.gender = "W"        super.init(name: name, age: age, gender: gender)    }}

注意到在Person中定義的gender是一個常量,所以我試圖在子類中對其進行初始化,是失敗的。錯誤資訊。



關於構造方法的知識,開起來似乎有點複雜,我們也可以分析下面兩站流程圖來分析上面我所提到的知識點。




四、 析構方法

Swift中的析構方法類似於objective-c中的dealloc的處理。

Demo:

class Dog {    deinit {        println("Dog Die")    }}func oneDog() {    var d = Dog()}println("New Dog")oneDog()println("Game Over")

oneDog函數執行完畢後,d變數被銷毀,Dog對象就失去了強引用,也就被銷毀了,會調用析構方法deinit

最終列印結果
"New Dog"
"Dog Die"
"Game Over"

註: 一個對象被釋放前,先自動調用自己的析構方法,然後一層一層往上調用父類的析構方法

著作權聲明:本文為博主原創文章,未經博主允許不得轉載。

Swift:物件導向(繼承與構造方法)

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.