ポリモーフィズムとは何ですか?
ポリモーフィズムは長い単語ですが、非常に単純な概念を表しています。
ポリモーフィズムは、クラスが共通のインターフェースを共有しながら異なる機能を持つオブジェクト指向プログラミング モデルを表します。
ポリモーフィズムの利点は、異なるクラスのコードでもすべて同じように動作するため、どのクラスが使用されているかを知る必要がないことです。
ポリモーフィズムは、現実世界のボタンにたとえることができます。ボタンの使い方は誰もが知っています。ボタンを押すだけです。ただし、ボタンが「実際に何であるか」は、ボタンが何に接続されているか、およびボタンが使用されるコンテキストによって異なりますが、その結果はボタンの使用方法には影響しません。上司がボタンを押すように指示した場合、あなたはそのタスクを実行するために必要な情報をすべてすでに持っています。
プログラミングの世界では、アプリケーションをよりモジュール化して拡張可能にするためにポリモーフィズムが使用されます。さまざまなクラスでアクションを記述する煩雑な条件文を作成するのではなく、ニーズに基づいて選択された交換可能なオブジェクトを作成できます。これがポリモーフィズムの基本的な目標です。
インターフェイス
インターフェイスは、コードを含めることができないことを除けば、クラスに似ています。インターフェイスではメソッド名とパラメータを定義できますが、メソッドの内容は定義できません。インターフェイスを実装するクラスは、そのインターフェイスで定義されているすべてのメソッドを実装する必要があります。クラスは複数のインターフェイスを実装できます。
「interface」キーワードを使用してインターフェイスを宣言します。
コードをコピーします コードは次のとおりです:
インターフェース MyInterface {
// メソッド
}
コードをコピー コードは次のとおりです:
class MyClassimplements MyInterface {
//methods
}
コードをコピーします コードは次のとおりです。
interface MyInterface {
public function doThis(); public function doThat ();
public function setName($name);
}
ここで定義されたすべてのメソッドは、それを実装するクラスのインターフェイスに記述されているように含める必要があります。 (以下のコード コメントを読んでください)
コードをコピー コードは次のとおりです:
//Legal VALIDclass MyClass は MyInterface {
protected $name;
public function doThis() {
// これを行うコード
}
public function doThat() {
// これを行うコードthat
}
public function setName($name) {
$this->name = $name;
}
}
// MyClass が実装するクラスが無効ですMyInterface {
// doThis() がありません!
プライベート関数 doThat() {
// これはパブリックである必要があります!
}
パブリック関数 setName() {
// がありませんname 引数!
}
}
抽象クラス 抽象クラス
抽象クラスはインターフェイスとクラスの混合物です。インターフェースと同じようにメソッドを定義できます。抽象クラスを継承するクラスは、抽象クラスで定義されているすべての抽象メソッドを実装する必要があります。
コードは次のとおりです: 抽象クラス MyAbstract {
// メソッド}
は、「extends」キーワードを使用してクラスにアタッチされます:
コードは次のとおりです: class MyClass extends MyAbstract {
// クラス メソッド}
通常のクラスと同様に、通常のメソッドと抽象メソッド (キーワードを使用) 「abstract」)をクラス内で定義したabstractに追加することができます。抽象メソッドはインターフェイスで定義されたメソッドと同様に動作し、それを継承する拡張クラスはまったく同じ定義を実装する必要があります。
コードは次のとおりです。 abstract class MyAbstract {
public $namepublic; function doThis( ) {
// これを実行します
}
abstract public function doThat();
abstract public function setName($name);
Web サイト上の記事を管理する Article クラスがあると仮定します。タイトル、著者、日付、カテゴリなどの記事に関する情報が含まれています。
次のようになります。
コードは次のとおりです。 コードをコピーします コードは次のとおりです: //.. interface Poly_writer_Writer { public function write(poly_base_Article $obj); } 非常に簡単で、Article オブジェクトを受け入れる public メソッド write() を定義しました。パラメータとして。 Writer インターフェースを実装するクラスには必ずこのメソッドがあります。 class Poly_writer_XMLWriter Poly_writer_Writer { public function write(poly_base_Article $obj) { $ret = ''; $ret .= ''; . ''; $ret .= ''; = ''; public function write(poly_base_Article $obj) { $array = array('article' => $obj); return json_encode($array); } コードをコピーしますコードは次のとおりです: コードをコピーします コードは次のとおりです。 コードをコピーコードは次のとおりです。
classpoly_base_Article {
public $title;
public $author;
public $category;
public function __construct($title, $author, $date, $category = 0) {
$this->title = $title;
$this->author = $author;
$this->date = $date; >$this->category = $category;
}
}
注: このチュートリアルのサンプル クラスでは、一般的な「package_component_Class」という命名規則が使用されています。名前の競合を避けるためにクラス名を仮想名前空間に分割する方法。
パブリック関数 write($type) {
$ret = '';
switch($type) {
case 'XML':
$ret = ' ';
$ret .= '';
$ret .= '' . $obj->date ';
$ret .= '' . $obj-> '';
case ':
$array = array(' 記事' => $obj);
$ret = json_encode($array);
}
return
}
}
このソリューションは醜いですが、少なくとも現時点では信頼できます。将来、さらにフォーマットを追加する必要があるときはどうなるのか、自問してみてください。このクラスを編集し続けて、ケースをどんどん追加することもできます
が、今はクラスを薄めている (FIX ME: 薄めている) だけです。
OOP の重要な原則は、クラスが 1 つのことを実行し、それを適切に実行する必要があるということです。
これを念頭に置くと、条件ステートメントは、クラスがさまざまなことを実行しようとしているという危険信号であるはずです。ここでポリモーフィズムが登場します。
この例では、記事の管理とそのデータのフォーマットという 2 つのタスクが明確に示されています。このチュートリアルでは、書式設定コードを新しいクラスにリファクタリングし、ポリモーフィズムの使用がいかに簡単であるかを発見します。
最初にインターフェイスを定義する必要があります。インターフェイスを変更すると、呼び出すコードも変更する必要があるため、インターフェイスを定義する方法を理解することが重要です。それ。
この例では、単純なインターフェイスを使用してメソッドを定義します:
コードをコピーします
コードは次のとおりです:
ヒント: メソッドや関数に渡されるパラメーターの型を厳密に制限したい場合は、write() メソッドで行ったように、poly_base_Article オブジェクト型のみを受け入れることができる型ヒントを使用できます。 Data
Data 。残念ながら、現在のバージョンの PHP では戻り値の型のヒントはサポートされていないため、戻り値の型には注意する必要があります。
ステップ 3: 実装を作成する
インターフェイスを定義したら、実際の作業を行うクラスを作成します。この場合、2 つの形式を出力する必要があります。このように、XMLWriter と JSONWriter という 2 つの Writer クラスが必要になります。渡された
次に、XMLWriter クラスの例を示します。
コードをコピーします。
コードは次のとおりです。
return $ret;
}
}
クラス定義からわかるように、インターフェースを実装するには、implements キーワードを使用します。 write() メソッドには、XML にフォーマットするための関数が含まれています。
次に、JSONWriter クラスを見てみましょう。
コードをコピー
class Poly_writer_JSONWriter は、poly_writer_Writer を実装します。 {
各形式に固有のコードは別のクラスに含まれています。各クラスは、他の形式ではなく、特定の形式を処理する単独の責任を負います。私たちのインターフェースのおかげで、アプリケーションの他の部分は、
を使用するためにこれがどのように機能するかを気にする必要はありません。
ステップ 4: 実装を使用する
新しいクラスが定義されたら、元の write() メソッドのすべてのコードが分離され、新しいカテゴリに入ります。
メソッドが今行う必要があるのは、次のようにこれらの新しいクラスを使用することだけです:
classpoly_base_Article {
//...
public function write(poly_writer_Writer $writer) {
return $writer->write($this)
}
}
Writer の取得
このメソッドには Writer オブジェクトを渡す必要があるため、どこから Writer オブジェクトを取得すればよいか疑問に思うかもしれません。
すべてはあなた次第で、戦略はたくさんあります。たとえば、ファクトリ クラスを使用してリクエスト データを取得し、オブジェクトを作成できます。
class Poly_base_Factory {
public static function getWriter() {
// リクエスト変数を取得
$format = $_REQUEST['format']
// クラス名を構築します。
$class = 'poly_writer_' . 'Writer';
if(class_exists($class)) {
// 新しい Writer オブジェクトを返します
return new $class ();
}
// それ以外の場合は失敗します
throw new Exception('Unsupported format')
}
}
前述のように、ニーズに応じて、他にも多くの戦略が利用可能です。この例では、リクエスト変数を使用して、使用する形式を選択します。リクエスト変数に基づいてクラス名を構築し、それが存在するかどうかを確認して
、新しい Writer オブジェクトを返します。その名前のクラスが存在しない場合は、例外をスローし、クライアント コードに次に何を行うかを決定させます。
ステップ 5: すべてをまとめる
すべてが整ったら、クライアント コードがどのようにまとめられるかを示します:
$article = new Poly_base_Article('Polymorphism', 'Steve', time(), 0);
try {
$writer = Poly_base_Factory::getWriter ();
}
catch (Exception $e) {
$writer = new Poly_writer_XMLWriter();
echo $article->write($writer );
まず、操作するサンプル Article オブジェクトを作成します。次に、Factory から Factory オブジェクトを取得し、例外が発生した場合はデフォルト (XMLWriter) にロールバックしようとします。
結論
このチュートリアルでは、ポリモーフィズムの概要を提供し、PHP のインターフェイスについて説明します。私が示しているのはポリモーフィズムの潜在的な使用例を 1 つだけ示していることを理解していただければ幸いです。
ポリモーフィズムは、OOP コード内の醜い条件文を回避するエレガントな方法です。これはコンポーネントを分離するという原則に従っており、多くの設計パターンに不可欠な部分です。ご質問がございましたら、お気軽にコメント欄にご質問ください。 翻訳元: http://net.tutsplus.com/tutorials/php/ Understanding-and-applying-polymorphism-in-php/
原文公開場所: http://ihacklog.com/?p = 4703