[PHP] インタフェースと抽象クラス、クラス継承、parent、this


Study / PHP    作成日付 : 2020/01/13 03:00:00   修正日付 : 2020/01/13 03:00:00

こんにちは。明月です。


前述でPHPのClassを宣言して使う方法に関して説明しました。

link - [PHP] functionとclass使用方法、アクセス修飾子、そしてstatic


PHPもクラスがあるのでインタフェース(interface)と抽象クラス(abstract class)があります。

個人的な考えはPHPにはデータタイプの指示子がないのでインタフェース役がコンパイル言語(javaやC#)より活用性が少ないではないかと思います。筆者も実際にPHPでInterfaceを使ったことがないですね。

でも抽象クラスはよく使います。

<?php
  $title = "title";
  // インタフェース
  interface ITest {
    function run();
  }
  // 抽象クラス(インタフェースITestを継承した。)
  abstract class AbstractTest implements ITest {
  // ITest インタフェースを継承したので、run関数を必ず宣言しなければならない。
  public function run() {
    return $this->print();
  }
  // 抽象メソッド
  protected abstract function print();
  }
  // 抽象クラス
  class Test extends AbstractTest {
    // AbstractTest 抽象クラスを継承したので「print」関数を必ず宣言しなければならない。
    protected function print() {
      return "Hello world";
    }
  }
  $obj = new Test;
?>
<!DOCTYPE html>
<html>
<head>
  <title>
  <?=$title?>
  </title>
</head>
<body>
  <?=$obj->run()?>
</body>
</html>


上の例をみればITestインタフェースとAbstract抽象クラスとTestクラスがあります。

依存層は「ITest -> AbstractTest -> Test」でなっています。それでTestを宣言してrunを実行すればAbstractTestのrunメソッドが実行してrunメソッド中では派生クラスの「print()」関数を呼び出す結果は「Helloworld」になります。


ここでparentとthisの概念ですね。

<?php
  $title = "title";
  interface ITest {
    function run();
  }
  abstract class AbstractTest implements ITest {
    private $data;
    public function run() {
      // $thisは実行しているクラスのメンバータイプ、つまりprint()関数が呼び出すこと
      return $this->print();
    }
    protected function setData($data) {
      // $this->dataはメンバー変数dataで$dataはパラメータdataだ。
      $this->data = $data;
    }
    protected function getData() {
      return $this->data;
    }
    protected abstract function print();
  }
  class Test extends AbstractTest {
    protected function print() {
      // 上位クラスのsetDataを呼び出す。
      // 参考でsetDataはprotectedタイプなので、派生クラスだけで参照が可能して外部では参照が不可能。
      parent::setData("Hello world");
      return parent::getData();
    }
  }
  $obj = new Test;
?>
<!DOCTYPE html>
<html>
<head>
  <title>
    <?=$title?>
  </title>
</head>
<body>
  <?=$obj->run()?>
</body>
</html>


$thisの場合は実行しているクラスのメンバーをさしています。すなわち、メンバー変数か関数を指しています。$thisの場合はC++のポインタの形で矢印で指示(->)をしています。

しかしparentの場合はparent::の形で指しています。&parent->の形ではエラーが発生します。文法が面白いですね。


上の例はobj->runを通ってAbstractTestのrunが呼び出してrun関数で抽象メソッドprintが呼び出します。

抽象メソッドprintが呼び出したのでTestクラスのprintが呼び出してprint関数で上位クラスのsetDataにデータを入れてgetDataでデータを持ってきて変換する形です。


私がデータを「Hello world」を入れたので結果は「Hello world」が出ます。

最新投稿