Swift3.0-實(shí)例方法

實(shí)例方法

實(shí)例方法是屬于某個(gè)特定類捧灰、結(jié)構(gòu)體或者枚舉類型實(shí)例的方法。實(shí)例方法提供訪問和修改實(shí)例屬性的方法或提供與實(shí)例目的相關(guān)的功能统锤,并以此來支撐實(shí)例的功能毛俏。

實(shí)例方法要寫在它所屬的類型的前后大括號(hào)之間。實(shí)例方法能夠隱式訪問它所屬類型的所有的其他實(shí)例方法和屬性饲窿。實(shí)例方法只能被它所屬的類的某個(gè)特定實(shí)例調(diào)用煌寇。實(shí)例方法不能脫離于現(xiàn)存的實(shí)例而被調(diào)用。

self 屬性(The self Property)

類型的每一個(gè)實(shí)例都有一個(gè)隱含屬性叫做self逾雄,self完全等同于該實(shí)例本身阀溶。你可以在一個(gè)實(shí)例的實(shí)例方法中使用這個(gè)隱含的self屬性來引用當(dāng)前實(shí)例。

class Person {
    var name: String?
    func setName(name: String) {
        self.name = name
    }
}

let person = Person()
person.setName(name: "Tom")
person.name    // Tom
在實(shí)例方法中修改值類型(Modifying Value Types from Within Instance Methods)

結(jié)構(gòu)體和枚舉是值類型鸦泳。默認(rèn)情況下银锻,值類型的屬性不能在它的實(shí)例方法中被修改。

但是做鹰,如果你確實(shí)需要在某個(gè)特定的方法中修改結(jié)構(gòu)體或者枚舉的屬性击纬,你可以為這個(gè)方法選擇可變(mutating)行為,然后就可以從其方法內(nèi)部改變它的屬性钾麸;并且這個(gè)方法做的任何改變都會(huì)在方法執(zhí)行結(jié)束時(shí)寫回到原始結(jié)構(gòu)中更振。方法還可以給它隱含的self屬性賦予一個(gè)全新的實(shí)例炕桨,這個(gè)新實(shí)例在方法結(jié)束時(shí)會(huì)替換現(xiàn)存實(shí)例。

要使用可變方法殃饿,將關(guān)鍵字mutating 放到方法的func關(guān)鍵字之前就可以了:

struct Point {
    var x = 0.0, y = 0.0
    mutating func moveByX(deltaX: Double, y deltaY: Double) {
        x += deltaX
        y += deltaY
    }
}
var somePoint = Point(x: 1.0, y: 1.0)
somePoint.moveByX(2.0, y: 3.0)
print("The point is now at (\(somePoint.x), \(somePoint.y))")
// 打印輸出: "The point is now at (3.0, 4.0)"

上面的Point結(jié)構(gòu)體定義了一個(gè)可變方法 moveByX(_:y:) 來移動(dòng)Point實(shí)例到給定的位置谋作。該方法被調(diào)用時(shí)修改了這個(gè)點(diǎn)芋肠,而不是返回一個(gè)新的點(diǎn)乎芳。方法定義時(shí)加上了mutating關(guān)鍵字,從而允許修改屬性帖池。

注意奈惑,不能在結(jié)構(gòu)體類型的常量(a constant of structure type)上調(diào)用可變方法,因?yàn)槠鋵傩圆荒鼙桓淖兯冢词箤傩允亲兞繉傩浴?/p>

let fixedPoint = Point(x: 3.0, y: 3.0)
fixedPoint.moveByX(2.0, y: 3.0)
// 這里將會(huì)報(bào)告一個(gè)錯(cuò)誤
在可變方法中給 self 賦值(Assigning to self Within a Mutating Method)

可變方法能夠賦給隱含屬性self一個(gè)全新的實(shí)例肴甸。上面Point的例子可以用下面的方式改寫:

struct Point {
    var x = 0.0, y = 0.0
    mutating func moveByX(deltaX: Double, y deltaY: Double) {
        self = Point(x: x + deltaX, y: y + deltaY)
    }
}

新版的可變方法moveByX(_:y:)創(chuàng)建了一個(gè)新的結(jié)構(gòu)體實(shí)例,它的 x 和 y 的值都被設(shè)定為目標(biāo)值囚巴。調(diào)用這個(gè)版本的方法和調(diào)用上個(gè)版本的最終結(jié)果是一樣的原在。

枚舉的可變方法可以把self設(shè)置為同一枚舉類型中不同的成員:

enum TriStateSwitch {
    case Off, Low, High
    mutating func next() {
        switch self {
        case .Off:
            self = .Low
        case .Low:
            self = .High
        case .High:
            self = .Off
        }
    }
}
var ovenLight = TriStateSwitch.Low
ovenLight.next()
// ovenLight 現(xiàn)在等于 .High
ovenLight.next()
// ovenLight 現(xiàn)在等于 .Off

上面的例子中定義了一個(gè)三態(tài)開關(guān)的枚舉。每次調(diào)用next()方法時(shí)彤叉,開關(guān)在不同的電源狀態(tài)(Off庶柿,LowHigh)之間循環(huán)切換秽浇。

類型方法 (Type Methods)

實(shí)例方法是被某個(gè)類型的實(shí)例調(diào)用的方法浮庐。你也可以定義在類型本身上調(diào)用的方法,這種方法就叫做類型方法(Type Methods)柬焕。

注意
在 Swift 中审残,你可以為所有的類、結(jié)構(gòu)體和枚舉定義類型方法斑举。每一個(gè)類型方法都被它所支持的類型顯式包含搅轿。

類型方法和實(shí)例方法一樣用點(diǎn)語(yǔ)法調(diào)用。但是富玷,你是在類型上調(diào)用這個(gè)方法介时,而不是在實(shí)例上調(diào)用。下面是如何在SomeClass類上調(diào)用類型方法的例子:

class SomeClass {
    class func someTypeMethod() {
        // type method implementation goes here
    }
}
SomeClass.someTypeMethod()

相當(dāng)于OC中的+方法(類方法)

在類型方法的方法體(body)中凌彬,self指向這個(gè)類型本身沸柔,而不是類型的某個(gè)實(shí)例。這意味著你可以用self來消除類型屬性和類型方法參數(shù)之間的歧義(類似于我們?cè)谇懊嫣幚韺?shí)例屬性和實(shí)例方法參數(shù)時(shí)做的那樣)铲敛。

下標(biāo)

下標(biāo)允許你通過在實(shí)例名稱后面的方括號(hào)中傳入一個(gè)或者多個(gè)索引值來對(duì)實(shí)例進(jìn)行存取褐澎。語(yǔ)法類似于實(shí)例方法語(yǔ)法和計(jì)算型屬性語(yǔ)法的混合。與定義實(shí)例方法類似伐蒋,定義下標(biāo)使用subscript關(guān)鍵字工三,指定一個(gè)或多個(gè)輸入?yún)?shù)和返回類型迁酸;與實(shí)例方法不同的是,下標(biāo)可以設(shè)定為讀寫或只讀俭正。這種行為由 getter 和 setter 實(shí)現(xiàn)奸鬓,有點(diǎn)類似計(jì)算型屬性:

subscript(index: Int) -> Int {
    get {
      // 返回一個(gè)適當(dāng)?shù)?Int 類型的值
    }

    set(newValue) {
      // 執(zhí)行適當(dāng)?shù)馁x值操作
    }
}

newValue的類型和下標(biāo)的返回類型相同。如同計(jì)算型屬性掸读,可以不指定 setter 的參數(shù)(newValue)串远。如果不指定參數(shù),setter 會(huì)提供一個(gè)名為newValue的默認(rèn)參數(shù)儿惫。

如同只讀計(jì)算型屬性澡罚,可以省略只讀下標(biāo)的get關(guān)鍵字:

subscript(index: Int) -> Int {
    // 返回一個(gè)適當(dāng)?shù)?Int 類型的值
}

下面代碼演示了只讀下標(biāo)的實(shí)現(xiàn),這里定義了一個(gè)TimesTable結(jié)構(gòu)體肾请,用來表示傳入整數(shù)的乘法表:

struct TimesTable {
    let multiplier: Int
    subscript(index: Int) -> Int {
        return multiplier * index
    }
}
let threeTimesTable = TimesTable(multiplier: 3)
threeTimesTable[1]  // 3

注意
TimesTable例子基于一個(gè)固定的數(shù)學(xué)公式留搔,對(duì)threeTimesTable[someIndex]進(jìn)行賦值操作并不合適,因此下標(biāo)定義為只讀的铛铁。

類型屬性語(yǔ)法

在 C 或 Objective-C 中隔显,與某個(gè)類型關(guān)聯(lián)的靜態(tài)常量和靜態(tài)變量,是作為全局(global)靜態(tài)變量定義的饵逐。但是在 Swift 中括眠,類型屬性是作為類型定義的一部分寫在類型最外層的花括號(hào)內(nèi),因此它的作用范圍也就在類型支持的范圍內(nèi)梳毙。

使用關(guān)鍵字 static 來定義類型屬性哺窄。在為類定義計(jì)算型類型屬性時(shí),可以改用關(guān)鍵字 class 來支持子類對(duì)父類的實(shí)現(xiàn)進(jìn)行重寫账锹。下面的例子演示了存儲(chǔ)型和計(jì)算型類型屬性的語(yǔ)法:

struct SomeStructure {
    static var storedTypeProperty = "Some value."
    static var computedTypeProperty: Int {
        return 1
    }
}
enum SomeEnumeration {
    static var storedTypeProperty = "Some value."
    static var computedTypeProperty: Int {
        return 6
    }
}
class SomeClass {
    static var storedTypeProperty = "Some value."
    static var computedTypeProperty: Int {
        return 27
    }
    class var overrideableComputedTypeProperty: Int {
        return 107
    }
}

class A: SomeClass {
    override class var overrideableComputedTypeProperty: Int {
        return 10
    }
}

注意
例子中的計(jì)算型類型屬性是只讀的萌业,但也可以定義可讀可寫的計(jì)算型類型屬性,跟計(jì)算型實(shí)例屬性的語(yǔ)法相同奸柬。

一個(gè)類可以繼承(inherit)另一個(gè)類的方法(methods)生年,屬性(properties)和其它特性。當(dāng)一個(gè)類繼承其它類時(shí)廓奕,繼承類叫子類(subclass)抱婉,被繼承類叫超類(或父類,superclass)桌粉。在 Swift 中蒸绩,繼承是區(qū)分「類」與其它類型的一個(gè)基本特征。

在 Swift 中铃肯,類可以調(diào)用和訪問超類的方法患亿,屬性和下標(biāo)(subscripts),并且可以重寫(override)這些方法押逼,屬性和下標(biāo)來優(yōu)化或修改它們的行為步藕。Swift 會(huì)檢查你的重寫定義在超類中是否有匹配的定義惦界,以此確保你的重寫行為是正確的。

可以為類中繼承來的屬性添加屬性觀察器(property observers)咙冗,這樣一來沾歪,當(dāng)屬性值改變時(shí),類就會(huì)被通知到雾消≡植可以為任何屬性添加屬性觀察器,無論它原本被定義為存儲(chǔ)型屬性(stored property)還是計(jì)算型屬性(computed property)仪或。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末确镊,一起剝皮案震驚了整個(gè)濱河市士骤,隨后出現(xiàn)的幾起案子范删,更是在濱河造成了極大的恐慌,老刑警劉巖拷肌,帶你破解...
    沈念sama閱讀 216,591評(píng)論 6 501
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件到旦,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡巨缘,警方通過查閱死者的電腦和手機(jī)添忘,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,448評(píng)論 3 392
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來若锁,“玉大人搁骑,你說我怎么就攤上這事∮止蹋” “怎么了仲器?”我有些...
    開封第一講書人閱讀 162,823評(píng)論 0 353
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)仰冠。 經(jīng)常有香客問我乏冀,道長(zhǎng),這世上最難降的妖魔是什么洋只? 我笑而不...
    開封第一講書人閱讀 58,204評(píng)論 1 292
  • 正文 為了忘掉前任辆沦,我火速辦了婚禮,結(jié)果婚禮上识虚,老公的妹妹穿的比我還像新娘肢扯。我一直安慰自己,他們只是感情好担锤,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,228評(píng)論 6 388
  • 文/花漫 我一把揭開白布蔚晨。 她就那樣靜靜地躺著,像睡著了一般妻献。 火紅的嫁衣襯著肌膚如雪蛛株。 梳的紋絲不亂的頭發(fā)上团赁,一...
    開封第一講書人閱讀 51,190評(píng)論 1 299
  • 那天,我揣著相機(jī)與錄音谨履,去河邊找鬼欢摄。 笑死,一個(gè)胖子當(dāng)著我的面吹牛笋粟,可吹牛的內(nèi)容都是我干的怀挠。 我是一名探鬼主播,決...
    沈念sama閱讀 40,078評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼害捕,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼绿淋!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起尝盼,我...
    開封第一講書人閱讀 38,923評(píng)論 0 274
  • 序言:老撾萬榮一對(duì)情侶失蹤吞滞,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后盾沫,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體裁赠,經(jīng)...
    沈念sama閱讀 45,334評(píng)論 1 310
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,550評(píng)論 2 333
  • 正文 我和宋清朗相戀三年赴精,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了佩捞。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 39,727評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡蕾哟,死狀恐怖一忱,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情谭确,我是刑警寧澤帘营,帶...
    沈念sama閱讀 35,428評(píng)論 5 343
  • 正文 年R本政府宣布,位于F島的核電站琼富,受9級(jí)特大地震影響仪吧,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜鞠眉,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,022評(píng)論 3 326
  • 文/蒙蒙 一薯鼠、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧械蹋,春花似錦出皇、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,672評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至,卻和暖如春纱注,著一層夾襖步出監(jiān)牢的瞬間畏浆,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,826評(píng)論 1 269
  • 我被黑心中介騙來泰國(guó)打工狞贱, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留刻获,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 47,734評(píng)論 2 368
  • 正文 我出身青樓瞎嬉,卻偏偏與公主長(zhǎng)得像蝎毡,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子氧枣,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,619評(píng)論 2 354

推薦閱讀更多精彩內(nèi)容