인스턴스가 아니라 타입에서 선언되는 메소드가 있다. 메소드를 선언하기 전에 static
키워드를 사용하자. 클래스는 서브클래스가 상위클래스 메소드를 오버라이딩할 수 있도록 class
키워드를 사용.
인스턴스 메소드처럼 .
연산자를 통해 호출하지만, 인스턴스를 만들지 않아도 타입 그 자체에서 바로 선언 가능하다는 게 타입 메소드의 특징이다.
class SomeClass {
class func someTypeMethod() {
// type method implementation goes here
}
}
SomeClass.someTypeMethod()
SomeClass
가 인스턴스가 아니라 클래스 타입임을 알 수 있다.
타입 메소드는 타입 이름을 앞에 적지 않아도 타입 메소드 이름만으로도 사용할 수 있다.
struct LevelTracker {
static var highestUnlockedLevel = 1
var currentLevel = 1
static func unlock(_ level: Int) {
if level > highestUnlockedLevel { highestUnlockedLevel = level }
}
static func isUnlocked(_ level: Int) -> Bool {
return level <= highestUnlockedLevel
}
@discardableResult
mutating func advance(to level: Int) -> Bool {
if LevelTracker.isUnlocked(level) {
currentLevel = level
return true
} else {
return false
}
}
}
highestUnlockedLevel
가 타입 메소드를 통해 관리되고 있다. 파라미터로 준 level
값이 더 크다면 highestUnlockedLevel
를 업데이트하는 unlock
, level
파라미터 값이 highestUnlockedLevel
이하라면 참을 리턴하는 isUnlocked
. 지금까지 입력된 level
중 최댓값을 유지하면서 값을 비교하는 메소드다.
타입 메소드와 타입 프로퍼티가 이 인스턴스를 사용하는 모든 이들이 참조 가능하다면 currentLevel
등 인스턴스 프로퍼티를 통해 이 인스턴스를 사용하는 이들의 개인적인 정보를 트래킹할 수도 있다.
class Player {
var tracker = LevelTracker()
let playerName: String
func complete(level: Int) {
LevelTracker.unlock(level + 1)
tracker.advance(to: level + 1)
}
init(name: String) {
playerName = name
}
}
var player = Player(name: "Argyrios")
player.complete(level: 1)
print("highest unlocked level is now \(LevelTracker.highestUnlockedLevel)")
// Prints "highest unlocked level is now 2"
player = Player(name: "Beto")
if player.tracker.advance(to: 6) {
print("player is now on level 6")
} else {
print("level 6 hasn't yet been unlocked")
}
// Prints "level 6 hasn't yet been unlocked"
Player
클래스를 통해 각 플레이어의 각 레벨을 트래킹하면서 최댓값을 타입 메소드, 타입 프로퍼티를 통해 가지고 있을 수 있다. 인스턴스 프로퍼티와 타입 프로퍼티와 값을 비교하는 advance
를 통해 현재 인스터스가 가지고 있는 레벨이 풀렸는지 체크한다.