【PHP応用】 継承
PHPには、クラスの継承という仕組みがあります。
以下の3つの特徴を持っています。
1.クラスを継承することで拡張できる。
2.拡張した子クラスは親クラスの内容を引き継ぐ。
3.子クラスは親クラスの内容を
上書きすることができる(できない場合もある)。
継承とは
あるクラス(親クラスとします)を拡張(extends)して、
別のクラス(子クラス・サブクラスとします)を
定義することを「継承」といいます。
その名の通り、親クラスのメソッドとプロパティを引き継ぎます。
このとき「private」修飾子が指定されているものは引き継がれないので注意しましょう。
メソッドとプロパティは、
サブクラスが同じ名前で上書き(オーバーライド)しない限り、親クラスの処理が保持されます。
継承を行うことで、複数のクラスの共通部分をまとめることができるため、重複した実装が不要になります。
継承の記述構文
class サブクラス extends 親クラス{ }
補足:親クラスの記述位置
クラスを自動的に読み込む機能(オートローディング)が有効になっていない場合、
クラスの記述は、インスタンス化したりするなど利用する記述より、前にある必要があります。
親クラスを継承するサブクラスを定義する場合、それより前に親クラスが宣言されている必要があります。
継承のサンプル
class Sample2_1_1 { public $a = "aaa"; public function showX(){ echo "xxx"; } } class Sample2_1_1_Sub extends Sample2_1_1{} class Sample2_1_1_Another{} $sub1 = new Sample2_1_1_Sub; echo $sub1->a; $sub1->showX(); $another = new Sample2_1_1_Another; //echo $another->a; //$another->showX();
→継承をしていると、親クラスのプロパティとメソッドを呼び出せていることがわかります。
オーバーライド
オーバーライドは、サブクラスが親クラスのメンバを上書きすることを言います。
(似たような言葉に「オーバーロード」というものもありますが、間違えないように注意しましょう。)
上書きするためには、同じ名前で再定義してあげればよいです。
オーバーライドのサンプル
class Sample2_1_2{ public $x = "xxx"; public function showX(){ echo $this->x; } } class Sample2_1_2_Sub extends Sample2_1_2{ public $x = "override:xxx<br>"; public function showX(){ parent::showX(); echo “子供がやったよ。” } $sub1 = new Sample2_1_2_Sub; echo $sub1->x; $sub1->showX();
★7行目や8行目をコメントアウトして、表示の違いを確認しましょう。
親クラスのメンバにアクセスする方法
ではオーバーライドした状態で、親クラスのメンバにアクセスしたい場合はどうすればよいでしょうか。
その場合は、「parent」キーワードを用います。
class Sample2_1_3{ private $x = "xxx"; protected static $y = "yyy"; public function method1(){ echo $this->x; } } class Sample2_1_3_Sub extends Sample2_1_3{ public $x = "override:xxx<br>"; public static $y = "override:yyy<br>"; public function method1(){ echo "override:" . $this->x;} public function method2(){ echo parent::method1();} public function method3(){ echo self::$y; } public function method4(){ echo parent::$y;} } $sub1 = new Sample2_1_3_Sub; echo $sub1->x; $sub1->method1(); $sub1->method2(); $sub1->method3(); $sub1->method4();
※プロパティの場合はstaticのついたプロパティでなければparentで呼び出すことはできません。
2階層の継承
親クラスを継承して子クラスを作成できましたが、その子クラスを親クラスとしてさらに子クラスを作成できます。
親→子→孫→・・・というように、継承関係はどんどんつなげていくことができるのです。
class Sample2_1_4{ public $a = “a”; } class Sample2_1_4_Kodomo extends Sample2_1_4{ public $b = “b”; } class Sample2_1_4_Mago extends Sample2_1_4_Kodomo{ public $c = “c”; } $mago = new Sample2_1_4_Mago; echo $mago->a;
→親クラスのプロパティが引き継がれていることが分かります。
補足:コンストラクタのオーバーライド
サブクラスでコンストラクタを定義時、
親クラスのコンストラクタが 暗黙的に呼び出されることはありません。
親クラスのコンストラクタを実行するには、子クラスのコンストラクタの 中で
「parent::__construct()」
と記述して呼び出す必要があります。
ただし、サブクラスでコンストラクタを定義していない場合は、通常のメソッドと同じく、
親クラスのコンストラクタを継承します。
この場合、親コンストラクターがprivateの場合は継承されないので、
親コンストラクターをpublicかprotectedにします。
補足:finalキーワード
finalキーワードがついているメソッドは、サブクラスから上書きできません。
finalキーワードがついているクラスは、拡張することができません。