オブジェクト指向プログラミングの基本的な特性の1つは、**継承**とカプセル化です。これらの機能により、実装の可読性を保ちつつ、複雑なアプリケーションロジックを容易に構築することができるようになります。
継承は、あるクラスの実装が他のクラスをベースにしていることを表現しています。OOPの用語では、descendant(継承するクラス)とancestor(継承するクラス)という言い方をします。
一般に、継承は子孫が祖先の持つすべての機能を取得し、祖先が持っていた機能をそのまま採用するか、独自の方法で変更するか、完全にオーバーライドして独自の実装を使用することで機能します。
この手法の利用範囲は非常に広く、多くのデザインパターンで継承が利用されている。
継承は、いわゆるプレゼンターの設計に適しており、これはMVCデザインパターンにおけるリンクロジックを表す特殊なクラスである。
例えば、ホームページ
、連絡先
、ログイン
の3つのページがあるとします。
各ページの実装では、多くのロジックが繰り返されます(たとえば、リクエストの受け付け、URLの作成、テンプレートのレンダリング、結果のHTMLの送信など)。そのため、このロジックで先祖を1つ実装し、子孫で使うだけというのが便利です。
まず、祖先を定義することから始めます(クラス名は重要ではありません、私はNetteフレームワークからの慣例を使用しています)。
abstract class BasePresenter{public function link(string $route, array $params = []): string{// URLを構築するためのメソッドの実装}public function renderTemplate(string $path, array $params = []): string{// テンプレート描画ロジック}}
クラスを定義するときに、新しい abstract
キーワードを使いました。これは、BasePresenter
クラスが抽象的であることを意味します。つまり、インスタンスを作ることはできず、他のクラスがそれを継承して実装するように使うだけでいいのです。抽象化には他にも有用な利点がありますが、それについては後述します。クラスは抽象的でなくても継承可能です - それは可能な設定のひとつに過ぎません。
ここで、2つ目のクラス、例えば HomepagePresenter
を実装することができます。
final class HomepagePresenter extends BasePresenter{public function run(): void{// レンダリングロジック$this->renderTemplate('主ページ', ['コンタクトリンク' => $this->link('お問い合わせ先:デフォルト'),]);}}
これで、HomepagePresenter
クラスが動作するようになりました。このクラスは final
であることに注意してください。つまり、もはや継承することができないので、メソッドは指定したとおりに使われることが保証されます。
このクラスを実装する際に、HomepagePresenter
だけが扱える run()
メソッドを新たに作成しました。このメソッドの内部では、クラスにはない renderTemplate()
メソッドと link()
を呼び出しています。しかし、これは問題ではありません。なぜなら、 extends
キーワードはメソッドがどこから継承されるかを教えてくれるので、それらが使用されるからです。
継承のおかげで、一度書いたメソッドを複数箇所で使用できるため、コードの再利用性を実現することができました。
継承の際に、特定のメソッドの動作をオーバーライドしておくと便利な場合が非常に多い。例えば、ContactPresenter
で先ほどの link()
メソッドの挙動を変更したい場合は、以下のようになります。
final class ContactPresenter extends BasePresenter{public function run(): void{// レンダリングロジックecho $this->link('ホームページ:デフォルト', []);}public function link(string $route, array $params = []): string{return 'https://baraja.cz';}}
実装をオーバーライドするには、子メソッドに再度メソッドを定義し、メソッドボディを上書きするだけです。インターフェースを満たし、同じ入力引数を実装することが重要である。
継承時に一部のメソッドを非表示にして、内部でのみ使用したい場合があります。あるいは、継承時にのみ使用できるようにし、パブリックインターフェースとしては使用できないようにします。
したがって、一般的には、いくつかの簡単な視認性のルールがあります。メソッドを public
, protected
または private
で表し、その可視性のルールは以下の通りである。
public
メソッドを呼び出すことができます。つまり、祖先と子孫の両方のインスタンスを作成するときに呼び出すことができます。protected
メソッドを呼び出すことができますが、インスタンス生成時に public インターフェースから呼び出すことはできません。これらは、継承を実現するための内部メソッドです(便利な応用例として、先ほどの例の link()
メソッドがあります)。private
メソッドを呼び出すことができます。非常に特殊なケースでは、実行時にメソッドの可視性を変更してから呼び出すと便利な場合があります。これは例えば、様々なDoctrineのライブラリで使用されています。
可視性を変更するには、次に PHP 自身が実装しているネイティブの ReflectionClass クラスを使用します。
Jan Barášek Více o autorovi
Autor článku pracuje jako seniorní vývojář a software architekt v Praze. Navrhuje a spravuje velké webové aplikace, které znáte a používáte. Od roku 2009 nabral bohaté zkušenosti, které tímto webem předává dál.
Rád vám pomůžu:
Články píše Jan Barášek © 2009-2024 | Kontakt | Mapa webu
Status | Aktualizováno: ... | ja