とぎぷろべい

包丁研ぎとプログラミングと米国株投資についてのなんやかんや

親クラスのメソッドの呼び出しについて(PHP)

f:id:feci:20210727001932j:plain

PHP7

 

PHP7.4.1における親クラスのメソッドの呼び出しについて

<?php

//cl1クラス
class cl1 {
  protected int $i1;                           //privateだとcl1_1クラスからアクセスできない
  //コンストラクター
  public function __construct(int $i1) {       //cl1インスタンス作成時のパラメータが$i1に入る
    $this->i1 = $i1;                           //i1プロパティに$i1の値を代入する
  }
  //i1プロパティのゲッター
  public function getI1($a = "個\n"): string { //getI1メソッド実行時のパラメータが$aに入る
    return $this->i1 . $a;                     //i1プロパティに$aを連結して返す
  }
}

//cl1のサブクラス
class cl1_1 extends cl1 {                      //extendsでcl1のサブクラスを作成
  private int $i2;
  //コンストラクター
  public function __construct(int $a, int $b) {
    //$this->i1 = $a;                          //推奨されない記述
    parent::__construct($a);                   //$aをパラメータに親クラスのコンストラクターを実行
    $this->i2 = $b;                            //$bをi2プロパティに代入
  }
  //i1プロパティのゲッター
  public function getI1($a = "冊\n"): string { //ここがオーバーライド
    return $this->i2 . $a;                     //i2プロパティに$aを連結して返す
  }
}


//実行
$cl1 = new cl1(5);        //cl1クラスのインスタンスの作成
echo $cl1->getI1();       //5個

$cl1_1 = new cl1_1(5,10); //cl1_1クラスのインスタンスの作成
echo $cl1_1->getI1();     //10冊

サブクラスから親クラスのメソッドを呼び出して使うには、parent::を使います。

 

parentは親クラスのことを意味しています。

そのparentにスコープ定義演算子であるダブルコロンを付けることで、そのあとに記述する親クラスのメソッドやプロパティを呼び出して実行することができます。

 

 

〇スコープ定義演算子(::)

スコープ定義演算子トークンのひとつです。

スコープ定義演算子を使うと、staticや定数、そしてオーバーライドされたクラスのプロパティやメソッドにアクセスすることができるらしいです。

 

 

トーク

トークンとは、ソースコード上の文字列をそれ以上分けることのできない最小単位に分けたもののことらしいです。

違う言い方をすると、ソースコードを意味のある最小単位に分けたものがトークンらしいです。

例:$get = $set + 28; のトークンは、$get=$set+28;の6つです。

 

 

閑話休題

 

上記のスクリプトでは、サブクラスcl1_1から親クラスcl1のコンストラクターを呼び出しています。

もともとこのコードでやりたいことは、cl1クラスのi1プロパティにサブクラスのコンストラクターの第1引数の値を代入したいだけです。

 

なのでひとつ上の行のコメントアウトしている部分のように $this->i1 = $a; と書けばいいじゃないかと思うのですが、どうやらこの方法はあまり推奨されてはいないようです。

このような場合にはparent::を使って親クラスのコンストラクターを呼び出してi1プロパティに値を代入してやるのが、PHPプログラマとしては賢い方法らしいです。

 

あとサブクラスのコンストラクターはどうあがいてもオーバーライドになります。

コンストラクターは名前を変えられませんからね。

 

そしてもしこのオーバーライドした状態で、親クラスのコンストラクターの引数が1つでサブクラスのコンストラクターの引数も1つだった場合はどうなるでしょうか。

もちろん、サブクラスのインスタンスからでは親クラスのコンストラクターを呼び出すことはできなくなってしまいます。

 

なのでこのような親クラスにもサブクラスにもコンストラクターがある場合には、上記スクリプトのようにサブクラスのコンストラクターの引数の数は親クラスのコンストラクターの引数の数+αとしてやるべきらしいです。

 

そうすれば、parent::__construct(引数1, ...); の記述を使うことで、サブクラスのインスタンスからでも親クラスのコンストラクターを実行することが可能になります。

 

 

以上です。