位置:首頁 > 高級語言 > Swift教學 > Swift類型方法

Swift類型方法

類型方法(Type Methods)

實例方法是被類型的某個實例調用的方法。你也可以定義類型本身調用的方法,這種方法就叫做類型方法。聲明類的類型方法,在方法的func關鍵字之前加上關鍵字class;聲明結構體和枚舉的類型方法,在方法的func關鍵字之前加上關鍵字static


注意:
在 Objective-C 裡麵,你隻能為 Objective-C 的類定義類型方法(type-level methods)。在 Swift 中,你可以為所有的類、結構體和枚舉定義類型方法:每一個類型方法都被它所支持的類型顯式包含。
 

類型方法和實例方法一樣用點語法調用。但是,你是在類型層麵上調用這個方法,而不是在實例層麵上調用。下麵是如何在SomeClass類上調用類型方法的例子:

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

在類型方法的方法體(body)中,self指向這個類型本身,而不是類型的某個實例。對於結構體和枚舉來說,這意味著你可以用self來消除靜態屬性和靜態方法參數之間的歧義(類似於我們在前麵處理實例屬性和實例方法參數時做的那樣)。

一般來說,任何未限定的方法和屬性名稱,將會來自於本類中另外的類型級彆的方法和屬性。一個類型方法可以調用本類中另一個類型方法的名稱,而無需在方法名稱前麵加上類型名稱的前綴。同樣,結構體和枚舉的類型方法也能夠直接通過靜態屬性的名稱訪問靜態屬性,而不需要類型名稱前綴。

下麵的例子定義了一個名為LevelTracker結構體。它監測玩家的遊戲發展情況(遊戲的不同層次或階段)。這是一個單人遊戲,但也可以存儲多個玩家在同一設備上的遊戲信息。

遊戲初始時,所有的遊戲等級(除了等級 1)都被鎖定。每次有玩家完成一個等級,這個等級就對這個設備上的所有玩家解鎖。LevelTracker結構體用靜態屬性和方法監測遊戲的哪個等級已經被解鎖。它還監測每個玩家的當前等級。

struct LevelTracker {
  static var highestUnlockedLevel = 1
  static func unlockLevel(level: Int) {
    if level > highestUnlockedLevel { highestUnlockedLevel = level }
  }
  static func levelIsUnlocked(level: Int) -> Bool {
    return level <= highestUnlockedLevel
  }
  var currentLevel = 1
  mutating func advanceToLevel(level: Int) -> Bool {
    if LevelTracker.levelIsUnlocked(level) {
      currentLevel = level
      return true
    } else {
      return false
    }
  }
}

LevelTracker監測玩家的已解鎖的最高等級。這個值被存儲在靜態屬性highestUnlockedLevel中。

LevelTracker還定義了兩個類型方法與highestUnlockedLevel配合工作。第一個類型方法是unlockLevel:一旦新等級被解鎖,它會更新highestUnlockedLevel的值。第二個類型方法是levelIsUnlocked:如果某個給定的等級已經被解鎖,它將返回true。(注意:儘管我們冇有使用類似LevelTracker.highestUnlockedLevel的寫法,這個類型方法還是能夠訪問靜態屬性highestUnlockedLevel)

除了靜態屬性和類型方法,LevelTracker還監測每個玩家的進度。它用實例屬性currentLevel來監測玩家當前的等級。

為了便於管理currentLevel屬性,LevelTracker定義了實例方法advanceToLevel。這個方法會在更新currentLevel之前檢查所請求的新等級是否已經解鎖。advanceToLevel方法返回布爾值以指示是否能夠設置currentLevel

下麵,Player類使用LevelTracker來監測和更新每個玩家的發展進度:

class Player {
  var tracker = LevelTracker()
  let playerName: String
  func completedLevel(level: Int) {
    LevelTracker.unlockLevel(level + 1)
    tracker.advanceToLevel(level + 1)
  }
  init(name: String) {
    playerName = name
  }
}

Player類創建一個新的LevelTracker實例來監測這個用戶的發展進度。它提供了completedLevel方法:一旦玩家完成某個指定等級就調用它。這個方法為所有玩家解鎖下一等級,並且將當前玩家的進度更新為下一等級。(我們忽略了advanceToLevel返回的布爾值,因為之前調用LevelTracker.unlockLevel時就知道了這個等級已經被解鎖了)。

你還可以為一個新的玩家創建一個Player的實例,然後看這個玩家完成等級一時發生了什麼:

var player = Player(name: "Argyrios")
player.completedLevel(1)
println("highest unlocked level is now \(LevelTracker.highestUnlockedLevel)")
// 輸出 "highest unlocked level is now 2"(最高等級現在是2)

如果你創建了第二個玩家,並嘗試讓它開始一個冇有被任何玩家解鎖的等級,那麼這次設置玩家當前等級的嘗試將會失敗:

player = Player(name: "Beto")
if player.tracker.advanceToLevel(6) {
  println("player is now on level 6")
} else {
  println("level 6 has not yet been unlocked")
}
// 輸出 "level 6 has not yet been unlocked"(等級6還冇被解鎖)