この記事では、PHP のオブジェクト指向プログラミング (OOP) について紹介します。オブジェクト指向の概念を使用して、より少ないコードでより優れたプログラムを作成する方法を示します。皆さんの幸運を祈ります。
オブジェクト指向プログラミングの概念には、作成者ごとに異なる見解があります。オブジェクト指向言語が持つべきものを思い出してください。
- データの抽象化と情報の隠蔽
- 継承
- ポリモーフィズム
PHP でカプセル化にクラスを使用する方法:
class Something {
// OOP では、クラスは通常、大文字で始まる名前になります。
var $x;
function setX($v) {
// メソッドは小文字で始まり、小文字で区切ります
// メソッド名の例 getValueOfArea()
$this->x=$v;
} }
function getX() {
return $this->x=$v;
もちろん独自の方法を使用することもできますが、標準を持っておくことは常に良いことです。
PHP のクラスのデータ メンバーは、値が割り当てられるまでは型を持ちません。データ メンバーは、整数、配列、連想配列 (連想配列)、またはオブジェクトの場合があります。メソッドは、クラス内の関数として定義されます。メソッド内のデータ メンバーにアクセスするには、次のように $this->name を使用する必要があります。このメソッド、それ以外の場合は、メソッドの関数のローカル変数です。
new を使用してオブジェクトを作成します
$obj = new Something;
次にメンバー関数
$obj->setX(5) を使用します;
$see = $obj->getX();
setX メンバー関数はオブジェクト (クラスではなく) obj のメンバー変数に 5 を代入し、getX は値 5 を返します。
$obj->x=6; のように、オブジェクト参照を使用してメンバー変数にアクセスすることもできます。ただし、これは適切なオブジェクト指向プログラミング方法ではありません。メンバー変数の値を設定するにはメンバー関数を使用し、メンバー変数を読み取るにはメンバー関数を使用することを強くお勧めします。メンバー関数を使用する以外はメンバー変数にアクセスできないと信じているなら、あなたは優れたオブジェクト指向プログラマーになれるでしょう。しかし残念ながら、PHP 自体には変数をプライベートとして宣言する方法がないため、不正なコードが存在することが許されています。
PHP の継承は extend を使用して宣言されます。
class Another extends Something {
var $y;
function setY($v) {
// メソッドは小文字で始まり、その後小文字を使用します
// メソッド名の単語の例 getValueOfArea()
$this->y=$v;
}
function getY() {
return $this ->y;
}
}
?>
このように、クラス「Another」のオブジェクトには、親クラスのすべてのメンバー変数とメソッド関数が含まれます。独自の
メンバー変数とメンバー関数。例:
$obj2=new Another;
$obj2->setY(7);
許可されません サポートされるため、クラスを複数のクラスから継承させることはできません。
継承されたクラスでは、「Another」で getX を再定義すると、「Something」で getX を再定義すると、メンバー関数 getX にアクセスできなくなります。親クラスと同名のメンバ変数が継承クラスで宣言されている場合、継承クラスの変数は親クラスの同名の変数を非表示にします。
クラスのコンストラクターを定義できます。コンストラクターはクラスと同じ名前のメンバー関数であり、クラスのオブジェクトを作成するときに呼び出されます。
class Something {
var $x;
function Something($y) {
$this->x=$ y;
}
関数 setX($v) {
$this->x=$v; return $this->x; 🎜>?>
したがって、次のメソッドを使用してオブジェクトを作成できます: ;
コンストラクターは値 5 をメンバー変数 x に自動的に割り当てます。コンストラクターとメンバー関数は通常の PHP です。関数を使用できるため、デフォルトのパラメータを使用できます。
function Something($x="3",$y="5")
その後:
$obj=new Something(); // x=3 and y=5
$obj=new Something(8); // x=8 および y=5
$obj=new Something(8,9); // x=8 および y=9
デフォルトパラメータの定義方法はCと同じなので、Yに値を渡すことはできませんが、実パラメータがなくなったらXにデフォルト値を渡します。関数はデフォルトのパラメータを使用します。
継承クラスのコンストラクタが呼び出された場合のみ、継承クラスのオブジェクトが作成され、親クラスのコンストラクタは呼び出されないのがPHPの特徴です。コンストラクター呼び出しチェーンは、オブジェクト指向プログラミングの特徴であるため、指向言語ではそうはいきません。基本クラスのコンストラクターを呼び出したい場合は、継承クラスのコンストラクターで明示的に呼び出す必要があります。これが機能するのは、親クラスのすべてのメソッドが継承されたクラスで使用できるためです。
function Another() {
$this->y=5;
$this->Something(); .
}
?>
オブジェクト指向プログラミングの優れたメカニズムは、抽象クラスを使用することであり、インスタンス化はできませんが、継承されたクラスのインターフェイスを定義するために使用されます。 。デザイナーは、プログラマに特定の基本クラスからのみ継承させるために抽象クラスを使用することがよくあるため、新しいクラスに必要な機能があることを確認できますが、PHP にはこれを行う標準的な方法はありません。基本クラスを定義するときにこの機能が必要な場合は、コンストラクターで「die」を呼び出すことでインスタンス化できないようにすることができます。継承されたクラスの場合、各関数で「die」を呼び出します。プログラマが基本クラスの関数を再定義せずに直接呼び出すと、エラーが発生します。さらに、PHP には型がないため、一部のオブジェクトは基本クラスから継承する継承クラスから作成されることを確認する必要があります。そのため、クラスを識別するメソッド (「何らかの識別子」を返す) を基本クラスに追加し、これを検証します。受け取ったときにオブジェクトにパラメータとして渡すと便利です。しかし、不正なプログラムに対する解決策はありません。不正なプログラムは継承されたクラスでこの関数を再定義できるため、通常、この方法は怠惰なプログラマにしか機能しません。もちろん、最善の方法は、プログラムが基本クラスのコードに触れないようにして、インターフェイスのみを提供することです。
オーバーロードは PHP ではサポートされていません。オブジェクト指向プログラミングでは、異なるパラメーターの型と数値を定義することによって、同じ名前のメンバー関数をオーバーロードできます。 PHP は型付けが緩い言語であるため、パラメーターの型のオーバーロードは役に立ちません。同様に、異なる数のパラメーターを使用したオーバーロードも機能しません。
オブジェクト指向プログラミングでは、コンストラクターをオーバーロードすると、さまざまな方法 (さまざまな数のパラメーターを渡すこと) でさまざまなオブジェクトを作成できる場合に便利です。ちょっとしたトリックでこれを行うことができます。
class Myclass {
function Myclass() {
$name="Myclass".func_num_args(); ->$name();
//$this->$name() は通常は間違っていますが、ここでは
//$name は呼び出すメソッドの名前を含む文字列です。 >}
関数 MyClass1 ($ x) {
コード;
}
関数 MyClass2 ($ x, $ y) {
コード; 🎜>}
?>
オーバーロードの目的は、このメソッドによって部分的に達成できます。
$obj1=new Myclass(1); //Myclass1 を呼び出します
$obj2=new Myclass(1,2); //Myclass2 を呼び出します
とても良い感じです。
ポリモーフィズム
ポリモーフィズムは、実行時にオブジェクトがパラメーターとして渡されたときに、どのメソッドを呼び出すかを決定するオブジェクトの機能として定義されます。たとえば、クラスを使用してメソッド "draw" を定義し、そのクラスを継承して円または正方形を描く "draw" の動作を再定義すると、パラメータ x を持つ関数が得られます。 call $x->draw( ) ポリモーフィズムがサポートされている場合、「draw」メソッドの呼び出しはオブジェクト x のタイプによって異なります。 PHP ではポリモーフィズムが当然サポートされています (C コンパイラでのこの状況を考えてください。コンパイルされた場合、どのメソッドが呼び出されますか? ただし、オブジェクトの型が何であるかはわかりません。もちろん、現在はそうではありません)。幸いなことに、PHP はポリモーフィズムをサポートしています。
function niceDrawing($x) {
//これがクラス Board のメソッドであるとします。
$x->draw(); }
$obj=new Circle(3,187);
$board->niceDrawing($obj); Circle の描画メソッドを呼び出します。
$board->niceDrawing($obj2); //PHP のオブジェクト指向プログラミング
?> を呼び出します。 🎜 >
純粋オブジェクト理論家は、PHP は真のオブジェクト指向言語ではないと信じており、これは正しいです。 PHP は、オブジェクト指向または従来の構造プログラミング手法と併用できるハイブリッド言語です。ただし、大規模なプロジェクトの場合は、純粋なオブジェクト指向のアプローチを使用してクラスを定義し、プロジェクト内でオブジェクトとクラスのみを使用する必要がある場合があります。プロジェクトが大きくなるほど、オブジェクト指向のアプローチを使用すると、保守が容易になり、理解しやすく、再利用しやすくなります。これがソフトウェアエンジニアリングの基本です。 Web サイトのデザインでこれらの概念を使用することが、将来の成功の鍵となります。
PHP の高度なオブジェクト指向テクノロジ
オブジェクト指向の基本概念を確認した後、さらに高度なテクノロジをいくつか紹介します。
シリアル化
PHP は永続オブジェクトをサポートしていません。オブジェクト指向言語では、永続オブジェクトは、アプリケーションによって複数回呼び出された後も状態と機能を保持するオブジェクトです。オブジェクトをファイルまたはデータベースに保存してから、オブジェクトを再ロードする方法。このメカニズムはシリアル化と呼ばれます。 PHP には、オブジェクトに対して呼び出すことができるシリアル化関数があり、オブジェクトを表す文字列を返します。次に、シリアル化関数は、メンバー関数の代わりにメンバー データを保存します。
PHP4 では、オブジェクトを文字列 $s にシリアル化し、そのオブジェクトを削除して、そのオブジェクトを $obj に逆シリアル化した場合でも、オブジェクトのメソッド関数を呼び出すことができます。ただし、(a) この機能は将来サポートされなくなる可能性があり、(b) シリアル化されたオブジェクトをディスクに保存してプログラムを終了するとファントムが発生するため、このアプローチはお勧めしません。シリアル化された文字列はメンバー関数を表していないため、このオブジェクトを逆シリアル化し、将来このスクリプトを再実行するときにオブジェクトのメソッドがまだ有効であることを期待することはできません。最後に、保存されたオブジェクトのメンバー変数をシリアル化することは、PHP では非常に便利です (連想配列と配列をディスクにシリアル化できます)。
例:
$obj=new Classfoo();
$str=serialize($obj);
// $str を次の場所に保存します。ディスク
//...数か月後
//ディスクから str をロード
$obj2=unserialize($str)
?>上記の例では、メンバー関数を使用せずにメンバー変数を復元できます (ドキュメントによると)。これにより、$obj2->x がメンバー変数にアクセスする唯一の方法
になります (メンバー関数がないため)。
この問題を解決する方法はいくつかありますが、このきれいな文書が台無しになってしまうため、それはあなたに任せます。
PHP が将来的にシリアル化を完全にサポートすることを願っています。
クラスを使用して保存データを操作
PHP とオブジェクト指向プログラミングの優れた点の 1 つは、何かを操作するクラスを簡単に定義し、必要に応じて適切なクラスを呼び出すことができることです。 HTML ファイルがあり、製品の ID 番号を選択して製品を選択する必要があるとします。データはデータベースに保存されており、価格などの製品情報を表示したいとします。さまざまな種類の製品があり、同じアクションでも製品ごとに異なる意味を持ちます。たとえば、サウンドの表示はその再生を意味しますが、他の製品ではデータベースに保存されている画像を表示することもあります。オブジェクト指向プログラミングと PHP を使用すると、より少ないコードで、より優れた方法で実行できます。
クラスを定義し、そのクラスが持つべきメソッドを定義し、継承によって各製品クラス (SoundItem クラス、ViewableItem クラスなど) を定義し、各製品クラスのメソッドを次のように再定義します。必要です。データベースに保存するテーブルの製品タイプ フィールドに基づいて、製品タイプごとにクラスを定義します。一般的な製品テーブルにはフィールド (ID、タイプ、価格、説明など) があります。スクリプトでは、データベース テーブルから型情報を取得し、対応するクラスのオブジェクトをインスタンス化します。
$obj=new $type(); -> ;action();
?>
これは、オブジェクトの型を気にせずに $obj の表示メソッドやその他のメソッドを呼び出すことができます。この手法を使用すると、新しいタイプのオブジェクトを追加するときにスクリプトを変更する必要がありません。このメソッドは少し強力です。タイプに関係なくすべてのオブジェクトが持つ必要があるメソッドを定義し、それらをさまざまなクラスでさまざまな方法で実装することで、スクリプト内のさまざまなタイプのオブジェクトにメソッドを使用できます。 , 二人のプログラマーが同じファイルで満足することはありません。プログラミングがこんなに楽しいものだと思いますか?メンテナンスの負担が少なく、再利用可能ですか?
プログラマーのグループを率いる場合、最善の方法は、各人が特定のクラスとオブジェクトを担当できるようにタスクを分割することです。国際化は、ユーザーが選択したさまざまな言語に適切なクラスを対応させるなど、同じ手法を使用して解決できます。
コピーとクローン
オブジェクト $obj を作成する場合、$obj2 = $obj を使用してオブジェクトをコピーできます。新しいオブジェクトは $obj のコピー (参照ではありません) です。したがって、代入後、新しいオブジェクトには同じ新しい状態の $obj が含まれます。場合によっては、これを望まず、単に obj と同じ新しいオブジェクトを作成し、new コマンドを使用したかのように新しいオブジェクトのコンストラクターを呼び出したい場合があります。これは、PHP のシリアル化と、他のクラスが継承する必要がある基本クラスを使用することによって実現できます。
危険ゾーンへの突入
オブジェクトをシリアル化すると、特定の形式の文字列が得られます。興味があれば、その秘密を調べてみるとよいでしょう。文字列はクラスの名前で、解凍できます:
$herring = Serialize($obj);
$vec =explode(": ",$herring) );
$nam = str_replace(""", "", $vec[2]);
?>
クラス「Universe」を作成し、すべてのクラスの継承元を使用するとします。 「Universe」:
class Universe {
function __clone() {
$herring=serialize($this) でクローン メソッドを定義できます。 ;
$vec=explode(":",$herring);
$nam=str_replace(""", "",$vec[2]);
$ret= new $nam;
return $ret;
}
}
//次に:
$obj=new Something()
/ /何かが Universe を拡張します !! >$other=$obj->__clone();
?>
取得するのは、 new を使用しているかのように、クラスの新しいオブジェクトであり、コンストラクターが呼び出されます。これがうまくいくかどうかはわかりませんが、Universe クラスが継承元のクラスの名前を知っていることは良い習慣です。あなたに課せられるのはあなたの想像力だけです! ! !
注: 私は PHP4 を使用しています。記事内の一部の内容は PHP3 には適していない可能性があります。
-終わり-