Swiftのstaticとclassの違いとは?初心者向けにやさしく解説!
生徒
「Swiftでstaticとclassの違いがいまいち分かりません。どっちを使えばいいのか迷います…」
先生
「それはとても大切なポイントですね。staticとclassは似ているようで実は役割が少し違うんですよ。」
生徒
「えっ、どっちもクラスの中で使って、共通の機能を作るんじゃないんですか?」
先生
「たしかに両方とも『インスタンス(実体)を作らなくても使える』点では似ていますが、classにはオーバーライドという強力な特徴があります。それを軸に見ていくと違いが分かりやすいですよ!」
1. staticとclassは何が違うの?
staticとclassは、どちらも「インスタンス化せずに使えるメソッドやプロパティ」を定義するために使います。これはつまり、「わざわざnewで作らなくても、クラス名だけで呼び出せる便利な機能」です。
たとえば、計算機アプリで「足し算」や「引き算」のような処理は、個々のインスタンスごとに持つ必要はありません。そんなときに便利なのがstaticやclassです。
2. staticは固定されたメソッドやプロパティ
staticを使うと、そのメソッドやプロパティは「変更されない固定のもの」になります。つまり、サブクラス(子クラス)で上書きできないのが特徴です。
例を見てみましょう。
class Animal {
static func sound() {
print("なんらかの動物の鳴き声")
}
}
class Dog: Animal {
// staticはオーバーライド(上書き)できないのでエラーになる
// override static func sound() {
// print("ワンワン")
// }
}
Animal.sound() // → なんらかの動物の鳴き声
Dogクラスでsoundメソッドを上書きしようとするとエラーになります。これがstaticの「変更できない」特徴です。
3. classは上書きできるメソッドやプロパティ
一方でclassを使うと、そのメソッドやプロパティはサブクラスで上書きできるようになります。つまり、overrideキーワードを使えば、動作を変えることができるのです。
class Animal {
class func sound() {
print("なんらかの動物の鳴き声")
}
}
class Dog: Animal {
override class func sound() {
print("ワンワン")
}
}
Dog.sound() // → ワンワン
Animal.sound() // → なんらかの動物の鳴き声
このように、親クラスと子クラスで異なる動作をさせたいときはclassを使います。
4. いつstatic、いつclassを使うべき?
変更されたくない機能であればstaticを使いましょう。たとえば定数や共通ユーティリティのように、「決まった処理だけを提供したい」ときに向いています。
拡張性をもたせたい場合にはclassを使います。サブクラスごとに処理を変えたいとき、つまりオーバーライド可能にしたいときに適しています。
5. staticとclassの使い分け 具体例
例えば、動物園のアプリを作るとしましょう。すべての動物に共通する「登録番号のフォーマット」は変更されたくないのでstaticで定義します。一方、動物の「鳴き声」は種類ごとに違うのでclassで定義します。
class Animal {
static let registerPrefix = "ZOO-"
class func sound() {
print("...")
}
}
class Cat: Animal {
override class func sound() {
print("ニャー")
}
}
print(Animal.registerPrefix + "001") // → ZOO-001
Cat.sound() // → ニャー
6. staticとclassの共通点と違いのまとめ表
| 特徴 | static | class |
|---|---|---|
| インスタンス不要で呼び出せる | ○ | ○ |
| サブクラスでオーバーライドできる | × | ○ |
| Swiftの構造体(struct)でも使える | ○ | × |
| 変更を防ぎたいとき | ◎ | △ |
| 拡張性を持たせたいとき | × | ◎ |
7. 構造体(struct)ではstaticしか使えない?
ここも大事なポイントです。Swiftではstruct(構造体)の中ではclassキーワードは使えません。つまり、構造体ではstaticしか使えないのです。
struct Utility {
static func showMessage() {
print("こんにちは!")
}
}
Utility.showMessage() // → こんにちは!
クラスと構造体の違いを意識しながら、適切に使い分けましょう。