LoginSignup
1
0

【PHP】オブジェクト指向の近道 - staticと転送コール

Last updated at Posted at 2022-11-15

staticプロパティとstaticメソッド

前回までは、インスタンスを生成してプロパティとメソッドを使いました。インスタンスのプロパティとメソッドとは別に、クラスのプロパティとメソッドにアクセスすることもできます。これらをstaticプロパティ(静的プロパティ)とstaticメソッド(静的メソッド、クラスメソッド)とよびます。staticプロパティとstaticメソッドはクラスごとにあり、プロパティやメソッドのようにインスタンスごとにはありません。

例えば、生成したインスタンス数$numberをもちたい時にstaticプロパティを使います。生成したインスタンス数はクラスごとの値ですので、staticプロパティに値をセットするのがよいです。また、staticプロパティにアクセスするだけのメソッドgetNumber()は、インスタンスにある必要がないのでstaticメソッドを使うのがよいです。

Person3のクラス定義です。staticをつけるだけで、staticプロパティ$numberstaticメソッド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メソッドにアクセスします。

staticプロパティにアクセス
        ++self::$number;

クラス外からはPerson3::getNumber()のように、クラス名を指定してstaticメソッドにアクセスします。

クラス外から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は使えません。

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

オブジェクト指向の近道(全5記事)

  1. なぜオブジェクト指向が必要か?
  2. クラスとインスタンス
  3. 継承とトレイト
  4. アクセス権とカプセル化
  5. staticと転送コール
1
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
0