- ベストアンサー
インタフェースと抽象クラスの使い方
インタフェースと抽象クラスの違いがいまいちよくわからないのですが、 違いではなく インタフェースにできて、抽象クラスではできないこと、 抽象クラスにできて、インタフェースにはできないこと をお伺いできますでしょうか。 宜しくお願いします。
- みんなの回答 (4)
- 専門家の回答
質問者が選んだベストアンサー
- ベストアンサー
インターフェイスは必要です。これは、メソッドの実装を保証してくれるからです。 例えば、何かのクラスを定義するとしましょう。このとき、インターフェイスを用意することで、そのメソッドが必ず実装されているものとみなして利用することができます。 例えば、インターフェイスAがあり、そこにABCというメソッドが宣言されているとします。そしてBというクラスがこのAを実装してあるとします。すると、このクラスBを利用する際、必ずそこにABCというメソッドがあるものとしてコードを書くことができるわけです。 クラスCでもクラスDでも、インターフェイスAが実装されていることがわかれば、そのABCメソッドを呼び出して利用する形で処理を構築できます。 抽象クラスでもそこにあるメソッドは保証されますが、インターフェイスはどんなクラスであっても、「追加するだけで特定のメソッドの実装が保証される」という特徴があります。なおかつ、必要であればいくつものインターフェイスを追加できます。こうした使い方は、抽象クラスでは行えません。
その他の回答 (3)
- world99
- ベストアンサー率64% (20/31)
同じインターフェースを実装したクラスは同じ変数にキャストすることができます。 クラスは違うがある処理をする同じ名前のメソッドを実行する場合に、この特徴が必要になります。 定義済みのCountableインターフェースを利用した例をあげます。 Countableインターフェースはcount()メソッドの実装を義務づけています。 1つめのインターフェース実装クラスCounterAは、 setCountメソッドで設定された値をcount()メソッドでリターンします。 class CounterA implements Countable { private $cnt = 0; public function setCount($cnt) { $this->cnt = $cnt; } public function count() { return $this->cnt; } } 2つめのインターフェース実装クラスCounterBは、 データベースから取得したあるデータの件数をcount()メソッドでリターンします。 class CounterB implements Countable { public function count() { return データベースから取得したあるデータの数; } } 2つのインターフェースを実行するクラス CounterAppを次のように定義します。 class CounterApp { private $obj; public function setCounter(Countable $obj) { $this->obj = $obj; } public function execute() { echo $this->obj->count(); } } CounterAppクラスのsetCounterメソッドの引数にCountableインターフェースを指定しています。 Countableインターフェースを実装しているクラスであれば引数に渡すことができます。 呼び出しは以下のようになります。 $app = new CounterApp(); $counter = new CounterA(); $counter->setCount(10); $app->setCounter($counter); $app->execute(); $counter = new CounterB(); $app->setCounter($counter); $app->execute(); 同じ抽象クラスを実装していても、サブクラス同士のキャストはできません。 また抽象クラスは、インスタンスを作成できないので変数の型には使用できません。
- root139
- ベストアンサー率60% (488/809)
> インタフェースという仕組みは必要でしょうか? メジャーな言語でインターフェースを採用しているのはJavaとPHPぐらいかと思います。 Java の様な静的型付けで単一継承の言語であれば、インターフェース(または多重継承が無いことを補完する仕組み)は無いと困りますが、動的型付け言語での必要性は微妙ですね・・・。 PHPも単一継承言語言語ですから、引数に取るクラスの継承関係を縛らずにタイプヒンティングを利用したいっていう時に必要とはなります。が、タイプヒンティング自体がPHPに必要かどうかも微妙ですし・・・。 http://www.php.net/manual/ja/language.oop5.typehinting.php
- world99
- ベストアンサー率64% (20/31)
インターフェースは、処理が実装されていないメソッドを宣言します。 実装したクラスで必ずメソッドを実装しなければならないです。 たとえば車、電車、自転車クラスを作るとします。 これらのクラスに共通して走るというメソッドを実装させたいけど、 その実装内容はクラス毎に違う場合にインターフェースを使います。 この例ですと、走るインターフェースを作成します。 【オブジェクト インターフェース】 http://www.php.net/manual/ja/language.oop5.interfaces.php 抽象クラスは、メソッドや変数が実装された状態で定義されており、 継承クラスでは呼び出すだけで利用できます。 抽象クラスでもメソッド宣言のはじめにabstract指定子を記述して インターフェースのように継承したクラスでオーバーライドしなければならないように実装できます。 例として、バス、タクシー、トラックの3つのクラスを作るとします。 3クラスとも車なので「走る」は同じだとします。 別々に定義すると3箇所同じ内容のメソッドを記入することになります。 この場合、車抽象クラスを使って、1箇所にまとめることができます。 もし「走る」の実装内容が違う場合は、abstract指定子をメソッドに宣言して 抽象クラスを継承したサブクラスで実装されることもできます。 【クラスの抽象化】 http://www.php.net/manual/ja/language.oop5.abstract.php
お礼
world99さん。ご回答ありがとうございます。 大変よく理解できました。 しかし、抽象クラスがあれば、いちいちインタフェースで作り込む必要はないよう思えるのですが、 インタフェースという仕組みは必要でしょうか?