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::
は、いい感じの転送コール