ホームページ >php教程 >php手册 >PHP におけるポリモーフィズムの理解と使用 [翻訳]

PHP におけるポリモーフィズムの理解と使用 [翻訳]

WBOY
WBOYオリジナル
2016-06-13 12:06:281032ブラウズ

ポリモーフィズムとは何ですか?
ポリモーフィズムは長い単語ですが、非常に単純な概念を表しています。
ポリモーフィズムは、クラスが共通のインターフェースを共有しながら異なる機能を持つオブジェクト指向プログラミング モデルを表します。
ポリモーフィズムの利点は、異なるクラスのコードでもすべて同じように動作するため、どのクラスが使用されているかを知る必要がないことです。
ポリモーフィズムは、現実世界のボタンにたとえることができます。ボタンの使い方は誰もが知っています。ボタンを押すだけです。ただし、ボタンが「実際に何であるか」は、ボタンが何に接続されているか、およびボタンが使用されるコンテキストによって異なりますが、その結果はボタンの使用方法には影響しません。上司がボタンを押すように指示した場合、あなたはそのタスクを実行するために必要な情報をすべてすでに持っています。
プログラミングの世界では、アプリケーションをよりモジュール化して拡張可能にするためにポリモーフィズムが使用されます。さまざまなクラスでアクションを記述する煩雑な条件文を作成するのではなく、ニーズに基づいて選択された交換可能なオブジェクトを作成できます。これがポリモーフィズムの基本的な目標です。
インターフェイス
インターフェイスは、コードを含めることができないことを除けば、クラスに似ています。インターフェイスではメソッド名とパラメータを定義できますが、メソッドの内容は定義できません。インターフェイスを実装するクラスは、そのインターフェイスで定義されているすべてのメソッドを実装する必要があります。クラスは複数のインターフェイスを実装できます。
「interface」キーワードを使用してインターフェイスを宣言します。

コードをコピーします コードは次のとおりです:


インターフェース MyInterface {
// メソッド
}


は、「implements」キーワードを使用してクラスにアタッチされます (複数のインターフェースはカンマで区切ることができます):

コードをコピー コードは次のとおりです:


class MyClassimplements MyInterface {
//methods
}

メソッドは、メソッド本体 (中括弧で囲まれた部分) がないことを除いて、クラスと同じようにクラスで定義できます。

コードをコピーします コードは次のとおりです。

interface MyInterface {
public function doThis(); public function doThat ();
public function setName($name);
}


ここで定義されたすべてのメソッドは、それを実装するクラスのインターフェイスに記述されているように含める必要があります。 (以下のコード コメントを読んでください)



コードをコピー コードは次のとおりです:

//Legal VALID

class 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 $name

public; function doThis( ) {
// これを実行します
}
abstract public function doThat();
abstract public function setName($name);


Web サイト上の記事を管理する Article クラスがあると仮定します。タイトル、著者、日付、カテゴリなどの記事に関する情報が含まれています。
次のようになります。



コードをコピーします

コードは次のとおりです。


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」という命名規則が使用されています。名前の競合を避けるためにクラス名を仮想名前空間に分割する方法。

次に、XML や JSON などのさまざまな形式で情報を出力するメソッドを追加します。次のようなことを行うとよいでしょう:


コードをコピーします コードは次のとおりです:

class Poly_base_Article {

//..
パブリック関数 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 つのタスクが明確に示されています。このチュートリアルでは、書式設定コードを新しいクラスにリファクタリングし、ポリモーフィズムの使用がいかに簡単であるかを発見します。

ステップ 2: インターフェイスを定義する
最初にインターフェイスを定義する必要があります。インターフェイスを変更すると、呼び出すコードも変更する必要があるため、インターフェイスを定義する方法を理解することが重要です。それ。
この例では、単純なインターフェイスを使用してメソッドを定義します:



コードをコピーします

コードは次のとおりです:

interface Poly_writer_Writer { public function write(poly_base_Article $obj); }

非常に簡単で、Article オブジェクトを受け入れる public メソッド write() を定義しました。パラメータとして。 Writer インターフェースを実装するクラスには必ずこのメソッドがあります。
ヒント: メソッドや関数に渡されるパラメーターの型を厳密に制限したい場合は、write() メソッドで行ったように、poly_base_Article オブジェクト型のみを受け入れることができる型ヒントを使用できます。 Data
Data 。残念ながら、現在のバージョンの PHP では戻り値の型のヒントはサポートされていないため、戻り値の型には注意する必要があります。
ステップ 3: 実装を作成する
インターフェイスを定義したら、実際の作業を行うクラスを作成します。この場合、2 つの形式を出力する必要があります。このように、XMLWriter と JSONWriter という 2 つの Writer クラスが必要になります。渡された

Article オブジェクトからデータを抽出し、情報をフォーマットするのは完全にこれらのクラス次第です。
次に、XMLWriter クラスの例を示します。



コードをコピーします。

コードは次のとおりです。

class Poly_writer_XMLWriter Poly_writer_Writer { public function write(poly_base_Article $obj) { $ret = ''; $ret .= ''; . '';

$ret .= '' .

$ret .= ''; = '';
return $ret;
}
}


クラス定義からわかるように、インターフェースを実装するには、implements キーワードを使用します。 write() メソッドには、XML にフォーマットするための関数が含まれています。
次に、JSONWriter クラスを見てみましょう。



コードをコピー

コードは次のとおりです。


class Poly_writer_JSONWriter は、poly_writer_Writer を実装します。 {

public function write(poly_base_Article $obj) { $array = array('article' => $obj); return json_encode($array); }


各形式に固有のコードは別のクラスに含まれています。各クラスは、他の形式ではなく、特定の形式を処理する単独の責任を負います。私たちのインターフェースのおかげで、アプリケーションの他の部分は、
を使用するためにこれがどのように機能するかを気にする必要はありません。
ステップ 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) にロールバックしようとします。

最後に、Writer オブジェクトを Article の write() メソッドに渡し、結果を出力します。

結論

このチュートリアルでは、ポリモーフィズムの概要を提供し、PHP のインターフェイスについて説明します。私が示しているのはポリモーフィズムの潜在的な使用例を 1 つだけ示していることを理解していただければ幸いです。
ポリモーフィズムは、OOP コード内の醜い条件文を回避するエレガントな方法です。これはコンポーネントを分離するという原則に従っており、多くの設計パターンに不可欠な部分です。ご質問がございましたら、お気軽にコメント欄にご質問ください。
翻訳元: http://net.tutsplus.com/tutorials/php/ Understanding-and-applying-polymorphism-in-php/
原文公開場所: http://ihacklog.com/?p = 4703

声明:
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。