staticプロパティとstaticメソッド
前回までは、インスタンスを生成してプロパティとメソッドを使いました。インスタンスのプロパティとメソッドとは別に、クラスのプロパティとメソッドにアクセスすることもできます。これらをstaticプロパティ(静的プロパティ)とstaticメソッド(静的メソッド、クラスメソッド)とよびます。staticプロパティとstaticメソッドはクラスごとにあり、プロパティやメソッドのようにインスタンスごとにはありません。
例えば、生成したインスタンス数$numberをもちたい時にstaticプロパティを使います。生成したインスタンス数はクラスごとの値ですので、staticプロパティに値をセットするのがよいです。また、staticプロパティにアクセスするだけのメソッドgetNumber()は、インスタンスにある必要がないのでstaticメソッドを使うのがよいです。
Person3のクラス定義です。staticをつけるだけで、staticプロパティ$numberとstaticメソッドgetNumber()を定義できます。
<?php
class Person
{
private $name;
public function __construct($name)
{
$this->name = $name;
}
public function getName()
{
return $this->name;
}
}
class Person3 extends Person
{
private static $number = 0;
public function __construct($name)
{
parent::__construct($name);
++self::$number;
}
public static function getNumber()
{
return self::$number;
}
}
$person_a = new Person3('suzuki');
$person_b = new Person3('tanaka');
$person_number = Person3::getNumber();
var_dump($person_number);
staticプロパティとstaticメソッドはクラスごとにある
転送コール
子クラスから親クラスのメソッドをコールしたい時はparent::を使います。self::やparent::を転送コールとよび、クラス定義でのみ使えます。parent::を使用して親クラスのメソッドを呼び出し、その後に処理を追加することで、子クラスのメソッドに追加の処理を挿入することができます。親クラスのメソッドを利用できるため、子クラスのメソッドでは変更分だけをコーディングするだけですみます。
parent::__construct($name);
クラス内ではself::で自クラスのstaticプロパティとstaticメソッドにアクセスします。
++self::$number;
クラス外からはPerson3::getNumber()のように、クラス名を指定してstaticメソッドにアクセスします。
$person_number = Person3::getNumber();
int(2)
インスタンス内は$this、クラス内はself::、親クラスはparent::でアクセス
staticメソッドからインスタンスのプロパティにはアクセスできません。
クラスから複数個のインスタンスが生成されるため、どのプロパティにアクセスするかを特定できないからです。
遅延静的束縛
PHPの中でも最強クラスの攻撃力がありそうな、遅延静的束縛でこの記事をしめたいと思います。転送コールparent:: self::で対応できないケースに、static::で転送コールする時に遅延静的束縛がおこります。
親クラスPersonでは親クラスのプロパティ$ageを、子クラスPerson2では子クラスのプロパティ$ageにアクセスしたい時に、転送コールstatic::を使います。転送コールself::$ageは常にPersonの$ageにアクセスしますし、Personに親クラスがないため、転送コールparent::$ageは使えません。
<?php
class Person
{
protected static $age = 26;
public static function getAge()
{
return static::$age;
}
}
class Person2 extends Person
{
protected static $age = 28;
}
$person_age = Person::getAge();
$person2_age = Person2::getAge();
var_dump($person_age);
var_dump($person2_age);
staticは直近の非転送コールPerson:: Person2::を保存して、そのクラスに動的に転送(Late Binding)します。
int(26)
int(28)
static::は、いい感じの転送コール


