インスタンスメソッドは、特定の型のインスタンスで呼び出されるメソッドです。また、型自体で呼び出せるメソッドを定義することもできます。こういったメソッドをタイプメソッドと呼びます。タイプメソッドには、メソッドの func
キーワードの前に static
キーワードを記述します。クラスでは、メソッドのスーパークラスでの実装を、サブクラスでオーバーライドすることを許可する class
キーワードを使うこともできます。
タイプメソッドは、インスタンスメソッドのように、ドットシンタックスで呼び出します。しかし、型のインスタンスではなく、その型でタイプメソッドを呼び出します。次の例は、SomeClass
クラスでのタイプメソッドの呼び出し方です。
class SomeClass {
class func someTypeMethod() {
// タイプメソッドの実装
}
}
SomeClass.someTypeMethod()
タイプメソッドの本体内では、self
プロパティが型のインスタンスではなく、その型自体を参照します。構造体と列挙型では、インスタンスプロパティとインスタンスメソッドパラメータのときと同じように、self
を使ってタイププロパティとタイプメソッドパラメータを区別することができます。
より一般的に、タイプメソッド内で使う限定しないメソッド名とプロパティ名は、型レベルの他のメソッドとプロパティを参照します。タイプメソッドは、型名を付ける必要なく、異なるメソッド名で別のタイプメソッドを呼び出すことができます。同様に、構造体や列挙型のタイプメソッドは、型名無しでタイププロパティの名前でタイププロパティにアクセスすることができます。
次の例では、ゲームの異なるレベルやステージについてのプレイヤーの進捗を記録する構造体 LevelTracker
を定義しています。1 人用のゲームですが、1 つのデバイスで複数プレイヤーの情報を保存できます。
ゲームをはじめて遊ぶとき、ゲームのレベルはすべて(レベル 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
プロパティを扱う 2 つのタイプ関数も定義しています。1 つ目はタイプ関数 unlockLevel
で、新しいレベルがアンロックされたときに highestUnlockedLevel
の値を更新します。2 つ目は便利なタイプ関数 levelIsUnlocked
で、特定のレベル値がすでにアンロックされている場合に true
を返します。(これらのタイプメソッドは、LevelTracker.highestUnlockedLevel
と記述することなく、タイププロパティ highestUnlockedLevel
にアクセスできることに注目してください。)
タイププロパティとタイプメソッドに加えて、LevelTracker
は各プレイヤーのゲームの進捗を記録します。インスタンスプロパティ currentLevel
を使って、プレイヤーが現在遊んでいるレベルを記録します。
currentLevel
プロパティを管理するために、LevelTracker
はインスタンスメソッド advanceToLevel
を定義しています。currentLevel
を更新する前に、このメソッドはリクエストされた新しいレベルがすでにアンロックされているかをチェックします。advanceToLevel(_:)
メソッドは実際に currentLevel
に設定できたか否かを示すブール値を返します。
構造体 LevelTracker
は、各プレイヤーの進捗を記録、更新するために、以下に示す Player
クラスで利用されます。
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
メソッドは、プレイヤーが特定のレベルを完了したときに呼び出されます。このメソッドはすべてのプレイヤーに次のレベルをアンロックします。プレイヤーの進捗を次のレベルに進めます。(前の行の LevelTracker.unlockLevel
の呼び出しによってレベルがアンロックされていることがわかっているため、advanceToLevel
の戻り値を無視しています。)
新しいプレイヤーのために Player
クラスのインスタンスを生成することができ、プレイヤーがレベル 1 を完了したときにどうなるのかを見てみましょう。
var player = Player(name: "Argyrios")
player.completedLevel(1)
print("highest unlocked level is now \(LevelTracker.highestUnlockedLevel)")
// "highest unlocked level is now 2" と出力
次のプレイヤーを生成し、まだどのプレイヤーもアンロックしていないゲームレベルに進めようとした場合、プレイヤーの現在のレベルを設定しようとして失敗します。
player = Player(name: "Beto")
if player.tracker.advanceToLevel(6) {
print("player is now on level 6")
} else {
print("level 6 has not yet been unlocked")
}
// "level 6 has not yet been unlocked" と出力
Portions of this page are translations based on work created and shared by Apple and used according to terms described in the Creative Commons Attribution 4.0 International License.