0.はじめに
swiftにはプロパティといってもたくさんのプロパティがあるため、整理してみようと思います。
1.プロパティの分類
プロパティの分類には2通りの分け方があります。
プロパティが紐づく対象による分類
・インスタンスプロパティ
・スタティックプロパティ
・クラスプロパティ
値を保持するかどうかによる分類
・ストアドプロパティ
・コンピューテッドプロパティ
このようにプロパティの分類には2通りの分け方があり、それぞれ3個、2個の分類があります。
2. プロパティが紐づく対象による分類
インスタンスプロパティ
struct Animal {
var name:String = "ライオン"
}
var lion = Animal()
print(lion.name) // ライオン
print(Animal.name) // エラー
その名の通り、インスタンスに紐づくプロパティです。
インスタンスからはアクセスできますが、クラスからはアクセス出来ません。
スタティックプロパティ
struct Animal {
static var needOxygen: Bool = true
}
var lion = Animal()
print(lion.needOxygen) // エラー
print(Animal.needOxygen) // true
クラスに紐づくプロパティです。
クラスからはアクセスできますが、インスタンスからはアクセスすることが出来ません。
クラスプロパティ
class Animal {
class var needOxygen: Bool {
get { return true }
}
}
var lion = Animal()
print(lion.needOxygen) // エラー
print(Animal.needOxygen) // true
スタティックプロパティと同様クラスに紐づくメソッドでアクセスの制限も同じですが、次のような違いがあります。
| オーバーライド | ストアドプロパティの定義 | コンピューテッドプロパティの定義 | |
|---|---|---|---|
| スタティックプロパティ | できない | できる | できる |
| クラスプロパティ | できる | できない | できる |
どちらかを利用するか迷ったときは、オーバーライドしたいときはクラスプロパティ、したくないときはスタティックプロパティという感じでいいと思います。
また構造体ではクラスプロパティが利用できないので注意が必要です。構造体そのものに紐付けたいときはstaticをつけましょう。
3. 値を保持するかどうかによる分類
ストアドプロパティ
struct Human {
var name = "hoge"
}
var human = Human()
human.name = "taro"
print(human.name)
その名の通り、値が保持される(stored)プロパティです。
またストアドプロパティには、値の変更を管理するプロパティオブザーバという機能があります。
struct Human {
var name = "hoge" {
willSet {
print("\(self.name)が\(newValue)に変更されます。")
self.name = newValue
}
didSet {
print("Human.nameに\(self.name)がセットされました。")
}
}
}
var human = Human()
human.name = "taro"
// hogeがtaroに変更されます。
// Human.nameにtaroがセットされました。
print(human.name) // taro
"hoge"に続くwillSet とdidSetがプロパティオブザーバの機能です。
willSetは値が代入される直前に呼ばれ、didSetは値が代入された直後に呼ばれます。
newValueには代入される値が格納されます。
コンピューテッドプロパティ
struct Customer {
var age: Int!
var drink:String {
get {
if self.age >= 20 {
return "お酒がおすすめです"
} else {
return "ソフトドリンクがおすすめです"
}
}
}
init?(age: Int) {
guard age >= 0 && age < 120 else { return nil }
self.age = age
}
}
var customer = Customer(age: 20)!
print(customer.drink) // お酒がおすすめです
customer.age = 18
print(customer.drink) // ソフトドリンクがおすすめです
その名の通り、値が計算されて(computed)出力されるプロパティです。
あくまで計算して値を返しているだけで、値を保持しているわけではないということを意識してください。
init?(失敗のあるイニシャライザ)とコンピューテッドプロパティに関しては下記のリンクで詳しく解説しているので、よければ御覧ください。
・失敗のあるイニシャライザって?
・get setってなんのこと?
本記事では2つの分類方法と、5つのプロパティの分類について整理してきました。整理できると楽しいですね!
参考文献