などの疑問や悩みを解決してまいります。
静的メンバ(static)とは
クラスに属するプロパティやメソッドそれぞれにstatic
キーワードを記述したものを静的メンバといいます。
静的メンバは、インスタンスを生成しなくてもクラスの内部・外部から直接アクセスできるようになります。
ポイント
- オブジェクトを生成せずにアクセス可能
クラスのインスタンスを作成する必要がなく、クラス名を使って直接アクセスします。 - クラス全体で共有される
静的プロパティやメソッドは、すべてのオブジェクトで共通のデータを保持します。
インスタンスごとに異なるデータを持つ通常のプロパティとは異なります。 self::
の使用
静的メンバにアクセスする場合、self::
を使います。self::
は現在のクラスを指します。
静的プロパティの例
以下のコードでは、$count
を静的プロパティとしたいので、static
キーワードを記述しています。
class MyClass {
// 静的プロパティ
public static $count = 0;
}
// クラス外から静的プロパティにアクセスして変更
echo MyClass::$count; // 0
MyClass::$count++; // 静的プロパティの値をインクリメント
echo MyClass::$count; // 1
静的プロパティとなった$count
は、クラス外からアクセスが可能となりますので、クラス名::静的プロパティ
でアクセスすることができます。
静的メソッドの例
以下のコードのように、クラス内で静的メンバにアクセスする場合はself::
を使用します。
class MyClass {
// 静的プロパティ
public static $count = 0;
// 静的メソッド
public static function increment() {
self::$count++;
}
// クラス内で別の静的メソッドを呼び出す
public static function displayCount() {
self::increment();
echo "Current count is: " . self::$count . "\n";
}
}
// クラス外からの静的メソッド呼び出し
MyClass::displayCount(); // Current count is: 1
MyClass::displayCount(); // Current count is: 2
static
キーワードを使うことでインスタンスを生成しなくても、簡単にクラスメンバにアクセスできる手軽さが魅力ですね!self::とstatic::とparent::
静的メンバにアクセスする方法として、self::
を解説しましたが、self::
以外にもstatic::
とparent::
があります。
それぞれの役割について解説していきます。
self::
self::
は、定義されているクラス自身を指し、クラス内でそのクラスの静的メンバにアクセスするために使用されます。
これは現在のクラスから直接呼び出され、継承されても常にそのクラス内で解決されます。
class A {
public static function who() {
echo "I am A";
}
public static function test() {
self::who(); // self::を使うと現在のクラスのwho()を呼び出す
}
}
class B extends A {
public static function who() {
echo "I am B";
}
}
B::test(); // "I am A" と出力される
現在のクラスのwho()
を呼び出すため、出力結果は「I am A」となります。
static::
static::
は、遅延静的束縛(Late Static Binding)を使用します。
これは、実際に呼び出しが行われるクラス(実行時のクラス)を指し、継承関係のあるクラスで動的にメソッドやプロパティを参照するのに適しています。
遅延静的束縛とは
クラスを継承した場合に、実行時に呼び出し元のクラスに基づいてメソッドやプロパティを解決する仕組みです。
クラス継承において、静的メソッドやプロパティを扱う際、self::
を使うと「そのメソッドが定義されたクラス」に基づいてメソッドやプロパティが参照されますが、継承関係のあるクラスで子クラスのメソッドを呼び出したい場合にはstatic::
を使用します。
class A {
public static function who() {
echo "I am A";
}
public static function test() {
static::who(); // static::を使うと実行時のクラスのwho()を呼び出す
}
}
class B extends A {
public static function who() {
echo "I am B";
}
}
B::test(); // "I am B" と出力される
上記のコードは、先のself::
の解説で使用したものほとんど同じで、違う箇所はself::
をstatic::
に変更したという部分だけです。
self::
は「メソッドが定義されたクラス」に基づいてメソッドを解決しますが、static::
は「メソッドを呼び出したクラス(実行時のクラス)」に基づいてメソッドを解決します。
遅延静的束縛のポイント
定義されたクラスではなく、実行時のクラスに基づく
parent::
parent::
は、親クラスのメソッドやプロパティを呼び出す際に使用されます。
子クラスから親クラスのメソッドをオーバーライドしている場合、親クラスの元のメソッドを呼び出すために使われます。
class A {
public static function who() {
echo "I am A";
}
}
class B extends A {
public static function who() {
echo "I am B";
}
public static function test() {
parent::who(); // parent::を使って親クラスのメソッドを呼び出す
}
}
B::test(); // "I am A" と出力される
parent::who()
は、子クラス内から呼び出されても、親クラスのwho()
を実行してくれます。
self::
、parent::
、static::
それぞれ特徴についての比較表です。
特徴 | self:: | static:: | parent:: |
---|---|---|---|
参照するクラス | 定義されたクラス(メソッドが定義されたクラス) | 実行時のクラス(呼び出し元のクラス) | 親クラス |
オーバーライドの影響 | 受けない(親のメソッドを常に呼び出す) | 受ける(オーバーライドされたメソッドを呼び出す) | 受けない(常に親のメソッドを呼び出す) |
用途 | 自クラス内で静的メソッドやプロパティを呼び出す時 | 遅延静的束縛を利用して、実行時のクラスのメソッドを呼び出す時 | 親クラスのメソッドを呼び出す時 |
実行時の挙動 | 常に定義されたクラスのメソッドが呼び出される | 実行時に呼び出されたクラスのメソッドが呼び出される | 常に親クラスのメソッドが呼び出される |
self::
、parent::
、static::
の比較表動的メンバ(インスタンス)とは
クラスから生成したインスタンス(オブジェクト)に関連付けられるプロパティやメソッドのことを動的メンバといいます。
動的メンバは、インスタンスが生成されていないと使用することができないので注意が必要です。
ポイント
- インスタンス(オブジェクト)ごとに独立
動的メンバは、各インスタンスで個別に保持されるため、複数のオブジェクト間で異なる状態を持つことができます。 - インスタンス生成後にアクセス可能
動的メンバにアクセスするためには、クラスのインスタンスを生成してから、そのインスタンスを介してプロパティやメソッドにアクセスします。 $this
キーワードを使用してアクセス
クラス内で動的メンバにアクセスする際は、$this
を使ってそのインスタンスのプロパティやメソッドを参照します。
動的プロパティの例
以下のコードのように、動的プロパティにアクセスする場合は、インスタンスを生成する必要があります。
class MyClass {
// 動的プロパティ
public $count = 0;
}
// オブジェクトを生成
$object1 = new MyClass();
$object2 = new MyClass();
// 動的プロパティへのアクセス
$object1->count = 5;
$object2->count = 10;
echo $object1->count; // 5
echo $object2->count; // 10
外部から動的メンバにアクセスする場合は、インスタンス名->動的プロパティ
でアクセスします。
動的メソッドの例
クラス内で動的メンバにアクセスする場合は、$this
を使用します。
class MyClass {
// 動的プロパティ
public $count = 0;
// 動的メソッド
public function increment() {
$this->count++;
}
// 動的メソッド
public function displayCount() {
echo "Current count is: " . $this->count . "\n";
}
}
// オブジェクトを生成
$object1 = new MyClass();
$object2 = new MyClass();
// オブジェクトごとにメソッドを呼び出し
$object1->increment();
$object1->displayCount(); // Current count is: 1
$object2->increment();
$object2->increment();
$object2->displayCount(); // Current count is: 2
まとめ
静的メンバと動的メンバの違いについて理解できましたでしょうか。
静的メンバはクラス全体で共通のデータや機能を提供し、動的メンバは各インスタンスに固有のデータを管理します。
それぞれの特性を理解することで、効率的なクラス設計が可能となりますので、ぜひ参考にしてください。