「PHPで、どのようにオブジェクト指向プログラミングをしていくか」を解説する連載。今回は、継承、オーバーライド、protected、parentの書き方と使い方、継承の設計についてコード例を交えて解説します。
本連載では、第1回の「PHPにおけるクラスの書き方と呼び出し方――インスタンス、メソッド、プロパティ」、第2回の「大規模PHP開発で欠かせないアクセス修飾子とカプセル化、アクセサー、コンストラクター/デストラクター」でPHPを例とした、オブジェクト指向について学んできました。
オブジェクト指向においてよく使われている機能の一つに「継承」があります。今回は、継承の意味や、継承、オーバーライド、protected、parentの基本的な書き方/使い方に加えて、継承を有効に活用するためのクラス設計の仕方などについて学んでいきましょう。
「継承」という日本語は、一般的に「受け継ぐこと」「身分や地位、財産や仕事などを受け継ぐ」という意味です。オブジェクト指向における「継承」も、「メソッドとプロパティを受け継ぐ」と捉えてよいでしょう。
まずは継承の一番基本的なところを、文法を含めて押さえていきましょう。下記コードをご覧ください。
<?php class hoge { public function A() { echo "call A\n"; } // private $i_ = 1; } // class foo extends hoge { public function B() { echo "call B\n"; } // private $j_ = 999; } // class hogeを使う $hoge_obj = new hoge(); $hoge_obj->A(); var_dump($hoge_obj); // class fooを使う $foo_obj = new foo(); $foo_obj->B(); $foo_obj->A(); // class fooには直接的にはないメソッドのcall var_dump($foo_obj);
まず「class hoge」の定義(3〜9行目)と使い方(19〜21行目)については、今までの連載で読み解けると思うので省略します。また、「class foo」のうち25行目の「$foo_obj->B();」については、同様に読み解けると思いますので、省略します。
一方で、26行目の「$foo_obj->A();」については、コメントにもある通り「fooには実装されていないメソッド」ですが、それにもかかわらず、問題なく動いています。これが「継承」です。つまり「class fooは、class hogeを受け継いだ」という状況になります。
「class foo」は「class hoge」のメソッドとプロパティを受け継いだので、「class foo」に実装がなくても、受け継いだ元である「class hoge」のA()メソッドを「まるで自分のメソッドのように」使えます。
またメソッドだけではなくプロパティも「受け継いでいる」ことが、26行目の「var_dump($foo_obj);」の結果から見てとれます。
object(foo)#2 (2) { ["j_":"foo":private]=> int(999) ["i_":"hoge":private]=> int(1) }
結果の4〜5行目に、class hogeのプロパティ「i」が出力されています。
このように、別のクラスからメソッドやプロパティを「受け継ぐ」ことを、オブジェクト指向では「継承」と言います。
書式はクラス宣言の所で下記のように書きます。「extends」というキーワードを覚えておくとよいでしょう。
class クラス名 extends 受け継ぎ元のクラス名
「受け継ぎ元(継承元)のクラス」と「受け継ぎ先(継承先)のクラス」の双方で、同一のメソッド名やプロパティ名が存在する可能性があります。その場合にどうなるのかを、コードを書いて確認してみましょう。
<?php class hoge { public function A() { echo "call hoge's A\n"; } // public $i_ = 1; } // class foo extends hoge { public function A() { echo "call foo's A\n"; } // public $i_ = 999; } // class fooを使う $foo_obj = new foo(); $foo_obj->A(); var_dump($foo_obj);
メソッド名やプロパティ名が「継承元と継承先で等しい」場合(4行目と11行目)、継承先のクラスのメソッドが優先的に使われます。これを「オーバーライド(override)」「上書き」と呼称しますので、覚えておくとよいでしょう。文字通り、継承先のメソッド/プロパティによって、継承元のメソッド/プロパティが「上書き」されます。
Copyright © ITmedia, Inc. All Rights Reserved.