PHP クラスの継承について
クラス
前回に引き続き今回もクラスについて記述していきたいと思います。
クラスの継承
クラス継承とはあるクラスのメンバ変数やメンバメソッドの情報を引き継いで、別のクラスでも参照できるようにすることをいいます。
継承元のクラスは基底クラスと呼ばれ、継承先のクラスは派生クラスと呼ばれています。
複数のクラスの共通となるような処理を基底クラスに記述しておけば、
継承を使用して複数の派生クラス側で参照させるなどといったことが可能になるので同じようなクラスを何度も定義しなくても済みます。
ただし基本的に基底クラスのメンバは派生クラスに引き継がれますが、前回記述したアクセス修飾子が privateのものは引き継がれません。
public もしくは protected の場合に派生クラスに引き継がせることができます。
継承の記述方法
継承する場合は派生クラスを作成する際に以下のように extends を用いて基底クラス名と派生クラス名を記述します。
class 派生クラス名 extends 基底クラス名{ 派生クラスの処理; }
すると派生クラスの処理で基底クラス側のメンバを参照できるようになります。
その後、派生クラスのオブジェクトを new でインスタンス化すると、
その派生クラスのオブジェクトを介して基底クラス内のメンバ変数に値を代入したり、メンバメソッドを実行したりといったことが可能になります。
継承のサンプル
以下では基底クラス側で定義したメンバ変数に値を代入して、基底クラス側のメンバメソッドを呼び出しています。
派生クラス側では特に処理は記述していません。
<?php class test{ public $atai1; public function func1(){ echo "これは基底クラスで記述しています。値は $this->atai1 です。"; } } class test_hasei extends test{ } $obj = new test_hasei(); $obj->atai1 = 10; $obj->func1(); ?>
結果は以下のように派生クラスのオブジェクトから基底クラスのメンバを参照できています。
ちなみに基底クラス内で $this->atai1 のようにしていますが、
$this はそのクラス自分自身で定義しているメンバ(プロパティ)にアクセスする際に用います。
そのクラス内で自分自身のメンバにアクセスするためにPHPであらかじめ決められているものです。
派生クラスからさらに派生クラスを作成する
PHPでは多重継承で複数の基底クラスを元に派生クラスを作成することはできませんが、
派生クラスからさらに継承した派生クラスを作成することはできます。
多重継承とは派生クラスを宣言する際に同時に基底クラスを複数継承することを言います。
PHPではサポートされていないので以下のようなことはできません。
<?php class test1{ public $atai1; public function func1(){ echo "これはtest1で記述しています。値は $this->atai1 です。"; } } class test2{ public $atai2; public function func2(){ echo "これはtest2で記述しています。値は $this->atai2 です。"; } class test_hasei extends test1, test2{ } $obj = new test_hasei(); $obj->atai1 = 10; $obj->atai2 = 20; $obj->func1(); $obj->func2(); ?>
ただし継承は何段階になってもできるので以下のように記述することは可能です。
<?php class test{ public $atai1; public function func1(){ echo "これは基底クラスで記述しています。値は $this->atai1 です。"; } } class test_hasei extends test{ } class test_hasei_hasei extends test_hasei{ } $obj = new test_hasei_hasei(); $obj->atai1 = 10; $obj->func1(); ?>
継承時のアクセス修飾子の違い
前回記載したように以下のようにアクセス修飾子によってアクセスできる範囲が異なります。
public はどこからでも参照可能
protected はそのクラス内と派生クラス内でのみ参照可能
private はそのクラス内でのみ参照可能
この内 private と protected の違いをクラスを継承して確認してみます。
サンプルコード
以下では private の値は派生クラスで参照できませんが、protected の値は派生クラスでも参照できています。
<?php class test{ private $priv_1 = 100; protected $prot_1 = 200; } class test_hasei extends test{ public function func(){ echo $this->priv_1; echo $this->prot_1; } } $obj = new test_hasei; $obj->func(); ?>
結果は以下のようになります。