私は最近 PHP のオブジェクト指向の部分を再学習し、その一部を私が紹介したものです。もっと意見を述べて一緒に学んでいただければ幸いです。
1. デストラクター: __destruct ()
//これはデストラクターであり、オブジェクトが破棄される前に呼び出されます
関数__destruct()
{
echo “さようなら”.$this->name.”
”;
}
2. コンストラクター: __construct()
PHP サブクラスは親クラスのコンストラクター メソッドを継承できますか?
サブクラス コンストラクターが定義されていない場合は、親クラス コンストラクターがデフォルトで呼び出されます。 サブクラスのコンストラクターが定義されている場合は、それ自体を直接呼び出します関数 __construct($name, $sex, $age)
$p1=新しい人(); //値をプライベート属性に直接割り当てると、値を割り当てるために __set() メソッドが自動的に呼び出されます。 $p1->name="張三"; $p1->sex="男性"; $p1->年齢=20; //プライベート属性の値を直接取得すると、__get() メソッドが自動的に呼び出され、メンバー属性の値が返されます。 echo "名前:".$p1->名前."
"; echo "性別:".$p1->性別."
"; echo "年齢:".$p1->年齢."
"; ?>
プログラムの実行結果: プライベート属性の値を直接設定する場合、__set() メソッドが自動的に呼び出され、プライベート属性に値が割り当てられます。 プライベート属性の値を直接設定する場合、__set() メソッドが自動的に呼び出され、プライベート属性に値が割り当てられます。 プライベート属性の値を直接設定する場合、__set() メソッドが自動的に呼び出され、プライベート属性に値が割り当てられます。 private 属性値を直接取得する場合は、__get() メソッドが自動的に呼び出されます。 名前:張三(チャン・サン) private 属性値を直接取得する場合は、__get() メソッドが自動的に呼び出されます。 性別: 男性 private 属性値を直接取得する場合は、__get() メソッドが自動的に呼び出されます。 年齢:20歳
上記のコードに __get() メソッドと __set() メソッドが追加されていない場合、プライベート メンバーはクラスの外で操作できないため、プログラムは誤動作します。 上記のコードは、__get() メソッドと __set() メソッドを自動的に呼び出すことで、カプセル化されたプライベート メンバーに直接アクセスするのに役立ちます。
クラス人
{
//以下はその人のメンバー属性です
private $name //人の名前;
private $sex //人の性別
private $age //人の年齢;
//__get() メソッドはプライベート属性を取得するために使用されます
プライベート関数 __get($property_name)
{
if(isset($this->$property_name))
{
return($this->$property_name);
}それ以外 {
戻り値(NULL);
}
}
//__set() メソッドはプライベート プロパティを設定するために使用されます
プライベート関数 __set($property_name, $value)
{
$this->$property_name = $value;
}
//__isset() メソッド
プライベート関数 __isset($nm)
{
echo "プライベートメンバーを測定するときに isset() 関数が自動的に呼び出されます
";
return isset($this->$nm);
}
//__unset() メソッド
プライベート関数 __unset($nm)
{
echo "プライベートメンバーを削除するためにクラス外で unset() 関数が使用されると自動的に呼び出されます
";
unset($this->$nm);
}
}
$p1=新しい人();
$p1->name="これは人の名前です";
// isset() 関数を使用してプライベート メンバーを測定する場合、完了を支援するために __isset() メソッドが自動的に呼び出され、戻り結果は true になります。
echo var_dump(isset($p1->name))."
";
echo $p1->name."
";
// unset() 関数を使用してプライベート メンバーを削除する場合、__unset() メソッドが自動的に呼び出され、タスクを完了して name private 属性を削除できるようになります。
unset($p1->name);
//削除されたため、この行には出力されません
echo $p1->name;?>
出力は次のとおりです。 isset() 関数は、プライベート メンバーを測定するときに自動的に呼び出されます。 ブール(真) これは人の名前です unset() 関数がクラス外でプライベート メンバーを削除するために使用されると、自動的に呼び出されます。 __set()、__get()、__isset()、__unset() これら 4 つのメソッドはすべてオブジェクトに追加され、必要に応じて自動的に呼び出されます。 オブジェクトの外部のオブジェクト内のプライベート プロパティに対する操作を完了するために使用されます。
header("Content-Type: text/html; charset=utf-8");
クラス人
{
//以下は人々のメンバー属性であり、すべてカプセル化されたプライベートメンバーです
private $name //人の名前
private $sex //人の性別
public $age //その人の年齢
関数 __construct($name, $sex, $age)
{
$this->name=$name;
$this->sex=$sex;
$this->age=$age;
}
関数say(){
echo "私の名前は:".$this->name."性別:".$this->性別."年齢:".$this->age;
}
}
クラス学生が Person を拡張します
{
var $school; //生徒がいる学校の属性
function __construct($name, $sex, $age,$school)
{
親::__construct($name,$sex,$age);
$this->school=$school;
}
//これが生徒の学習方法です
関数の勉強()
{
echo "私の名前は:".$this->name." 私は ".$this->school." で勉強しています。";
}
//これは学習して話すことができるメソッドであり、そのすべての属性について説明し、親クラスの同じ名前のメソッドをカバーします
。 関数say()
{
//親クラスの「クラス名::」を使用して、親クラスでオーバーライドされたメソッドを呼び出します;
// 人::say();
//または、「parent::」メソッドを使用して、親クラスでオーバーライドされたメソッドを呼び出します;
親::say();
//独自の関数をいくつか追加します
echo "私の年齢は:".$this->age."私は ".$this->school" の学校に通っています。
";
}
}
$p1 = 新入生("王耀峰","男性","22","河南科学技術大学");
$p1->say();
?> 結果: 私の名前は:wangyaofeng 性別:男性 年齢:22 歳:22 河南科学技術大学で勉強しています
最終関数say()
{}} クラス学生は人を拡張します {
関数say()
{}} 次のエラーが発生します。 致命的なエラー: 最終メソッド Person::say() をオーバーライドできません
7.static キーワードと const キーワードの使用静的
Static キーワードは、クラス内のメンバー属性とメンバー メソッドを静的として記述します。先ほど、「person」クラスに「person」を追加すると、静的メンバーの利点は何でしょうか。このように、「人」クラスを使用して数百以上のインスタンス オブジェクトをインスタンス化し、各オブジェクトは「属する国」の属性を持ちます。開発されたプロジェクトが中国人向けの場合、各オブジェクトは「中国」という国属性があり、他の属性は異なります。「国」属性を静的メンバーにすると、メモリ内には国属性が 1 つだけ存在し、これらの数百以上のオブジェクトがこの属性を共有します。
静的メンバーはクラスに属し、どのオブジェクトインスタンスにも属さないため、メンバーは外部アクセスを制限できます。他のクラスはアクセスできず、共有専用です。クラスのインスタンスは、クラスのメンバーをある程度保護できます。メモリの観点から分析してみましょう。メモリは論理的に 4 つのセグメントに分けられ、オブジェクトは「ヒープ メモリ」に配置され、オブジェクトの参照は「スタック メモリ」に配置され、静的メンバは「初期化」に配置されます。 "。「静的セクション」は、クラスが初めてロードされるときに配置され、以下に示すように、ヒープ メモリ内のすべてのオブジェクトで共有できます。クラスの静的変数はグローバル変数に非常に似ており、次のように共有できます。クラスのすべてのインスタンスも同様であり、グローバル関数と同様です。
クラス人{//以下は人々の静的メンバー属性ですpublic static $my Country="中国";// var $name // その人の名前;//これは people の静的メンバー メソッドですパブリック静的関数say(){エコー「私は中国人です
」;}}//静的プロパティを出力するエコー パーソン::$my Country;//静的メソッドにアクセスする人::say();//静的プロパティを再割り当てする人::$my Country="米国";エコー 人::$my Country;
?> 静的メンバーはクラスが初めてロードされるときに作成されるため、クラス外のオブジェクトは必要なく、クラス名を使用するだけです 前述のように、静的メンバーにアクセスするには、このクラスの各インスタンス オブジェクトで共有されているため、オブジェクト を使用します。 クラス内の静的メンバーにアクセスできますか? 上の図から、すべてのオブジェクト内に静的メンバーが存在するわけではないことがわかります
はい、ただしすべてのオブジェクトは共有できるため、オブジェクトを使用してメンバーにアクセスする場合、そのような属性定義は存在しません
Java などの他のオブジェクト指向言語では、オブジェクトを使用して静的メンバーにアクセスできます。 静的メンバーについて質問します。PHP でオブジェクトを使用して静的メンバーにアクセスできる場合、それらは静的であるため、使用しないようにすべきです
プロジェクトに取り組んでいるときの目的は、クラス名 (
person::$my Country="United States";
) を使用してメンバーにアクセスすることです。
クラス内の静的メソッドは、クラスの静的属性にのみアクセスできます。クラス内の静的メソッドは、クラスの非静的メンバーにはアクセスできません
、理由は非常に簡単です。このクラスのメソッドでこのクラスの他のメンバーにアクセスしたい場合は、$this 参照を使用する必要があります。 参照ポインター $this は、このメソッドを呼び出すオブジェクトを表します。前述したように、静的メソッドはオブジェクトではなく
で呼び出されます。 クラス名を使用してアクセスするため、オブジェクトはまったく存在せず、$this への参照がなければ、 への参照はありません。 クラス内の非静的メンバーにはアクセスできません。クラス内の静的メンバーはオブジェクトなしでアクセスできるため、クラス内の 静的メソッドはクラスの静的プロパティにのみアクセスできます。 $this が存在しないため、静的メソッド内の他の静的メンバーにアクセスするには
を使用します。 これは特別なクラス「self」です。
self は、この静的メソッドが配置されているクラスを表す点を除いて、$this と似ています。それで
静的メソッドでは、メソッドが配置されているクラスの「クラス名」を使用できます
、「self」を使用して他の静的メンバーにアクセスすることもできます
特別な事情がない限り、通常は後者の「self::member 属性」メソッドを使用します。
コードスニペット
クラス人{
//以下は人々の静的メンバー属性ですpublic static $my Country="中国";//これは人間の静的メンバー メソッドであり、self を通じて他の静的メンバーにアクセスしますパブリック静的関数say(){
echo "私は".self::$my Country."
";
}
}//静的メソッドにアクセスする人::say();
?>{
静的メンバーに非静的メソッドでアクセスすることは可能ですか? もちろん可能ですが、「$this」参照は使用できません
クラス名または「self::member 属性形式」も使用します。
const は定数を定義するキーワードです。PHP で定数を定義するには、「define()」関数を使用します。 ただし、クラス内で定数を定義する場合は、キーワード「const」が使用されます。 C の #define に似ています。プログラム内で値が変更された場合、
その場合、「const」で変更されたメンバー属性のアクセス方法と、「static」で変更されたメンバーのアクセス方法が異なります
それほど多くはなく、メソッド内で「クラス名」と「self」キーワードを使用するだけです。ただし、「$」記号を使用する必要はありません。また、 も使用できません。 オブジェクトを使用してアクセスします。 コードスニペット
クラス私のクラス
//定数定数を定義する
echoconst 定数 = '定数値';関数 showConstant() {
self::constant . "n" //アクセスには self を使用し、"$" を追加しないでください。}
echo MyClass::constant . "n"; // "$" を追加せずにクラス名を使用してアクセスします。}
$class = 新しい MyClass();$class->showConstant();// echo $class::constant は許可されません。?>8.__toString() メソッド
以前、クラス(PHPが提供する)で「--」で始まるメソッド名を宣言する方法があるときのことをお話しました
さまざまな状況で自動的に呼び出されて実行されるメソッド。「__toString()」メソッドも自動的に呼び出され、ペアを直接出力します。 前に述べたように、オブジェクト参照はポインタです。たとえば、「$p=new Person()」では、$p
となります。 これは単なる参照です。echo を使用して $p を直接出力することはできません。それ以外の場合は、「キャッチ可能な致命的なエラー:
のオブジェクト」が出力されます。 クラス内で定義すると「クラス Person を文字列に変換できませんでした」エラー
「__toString()」メソッドは、オブジェクト参照を直接出力する場合、エラーにはならずに自動的に呼び出されます
「__toString()」メソッドは「__toString()」メソッドで返された文字を出力するため、「__toString()」メソッドは1つです
戻り値 (return ステートメント) が必要です。 コードスニペット
// 単純なクラスを宣言します
クラス TestClass
{パブリック $foo;
パブリック関数 __construct($foo) {$this->foo = $foo;}// __toString メソッドを定義し、メンバー属性 $foo を返すパブリック関数 __toString() {$this->foo を返します。}$class = new TestClass('Hello');}
//オブジェクトを直接出力する。 オブジェクトを再作成する場合は、同じ属性を割り当てます。これはより面倒でエラーが発生しやすいため、オブジェクトをベースにする必要があります$クラスをエコー;?>上記の例の出力: Hello9. オブジェクトのクローンを作成します「new」キーワードを使用する場合、プロジェクト内で 2 つ以上の同一のオブジェクトを使用する必要がある場合があります
。 同一のオブジェクトを完全に複製することが非常に必要であり、複製後は 2 つのオブジェクトが相互に干渉しなくなります。
PHP5 では、オブジェクトのクローンを作成するために「clone」キーワードを使用します。
コードスニペット
クラス人{
//以下はその人のメンバー属性ですvar $name //人の名前;var $sex //人の性別;var $age // 人の年齢;//属性名 $name、性別 $sex、年齢 $age に値を割り当てるコンストラクター パラメーターを定義します。function __construct($name="", $sex="", $age=""){
$this->name=$name;$this->sex=$sex;$this->age=$age;
}//この人の話し方で、自分の属性がわかる関数say(){
echo "私の名前は:".$this->name." 性別: ".$this->性別" 私の年齢: ".$this->age."
";
}
}$p1=新しい人("張三", "男性", 20);//「clone」を使用して、p1 オブジェクトと同じプロパティとメソッドを持つ新しいオブジェクト p2 を複製します。$p2=クローン $p1;$p2->say();
?>クラス人
PHP5 では、オブジェクトのクローン作成時に自動的に呼び出される特別なメソッド名「__clone()」メソッドが定義されています。 クローン作成後に元のオブジェクトを変更したい場合は、「__clone()」メソッドで元のオブジェクトと同じプロパティとメソッドを持つオブジェクトを作成します。 コンテンツを変更するには、__clone() の元の属性とメソッドを書き直す必要があります
「__clone()」メソッドにはパラメーターを含めることはできませんが、自動的に
が含まれます。 2 つのポインター
$this
と $that が含まれており、$this は コピー を指し、$that はオリジナルを指します。 コードスニペット
{
//以下はその人のメンバー属性ですvar $name //人の名前;var $sex //人の性別;var $age // 人の年齢;//属性名 $name、性別 $sex、年齢 $age に値を割り当てるコンストラクター パラメーターを定義します。function __construct($name="", $sex="", $age=""){
$this->name=$name;$this->sex=$sex;$this->age=$age;
}//この人の話し方で、自分の属性がわかる関数say(){
echo "私の名前は:".$this->name." 性別: ".$this->性別" 私の年齢: ".$this->age."";
}//オブジェクトの複製時に自動的に呼び出されるメソッド。複製後に元のオブジェクトの内容を変更したい場合は、__clone()で元の属性とメソッドを書き換える必要があります。関数__clone(){
//$this はコピー p2 を指し、$that は元の p1 を指すため、このメソッドではコピーの属性が変更されます。$this->name="私は偽の $that->name";$this->年齢=30;
}
上記の例の出力:
}$p1=新しい人("張三", "男性", 20);$p2=$p1 のクローンを作成します。$p1->say();$p2->say();?>
実行結果
私の名前:張三 性別:男性 年齢:20歳
私の名前:偽張三です 性別:男性 年齢:30歳
10.__call は呼び出しエラーを処理します
プログラム開発において、オブジェクトを使用してオブジェクトの内部メソッドを呼び出すときに、呼び出されたメソッドが存在しない場合、プログラムは
エラーが発生するとプログラムが終了し、実行を続行できなくなります。それで、プログラムがオブジェクト内に存在しないメソッドを呼び出したときにプロンプトを表示できますか
呼び出されたメソッドと使用されたパラメーターは存在しませんが、プログラムは実行を続行できます。この時点では、呼び出しに存在しないメソッドを使用する必要があります
。 メソッド「__call()」は、メソッドが使用されると自動的に呼び出されます。コードスニペット
//これはテストクラスであり、属性やメソッドはありませんクラステスト{}//Testクラスのオブジェクトを生成$test=新しいテスト();//オブジェクトに存在しないメソッドを呼び出す$test->demo("one", "two", "three");//このメソッドは存在しません//ここではプログラムは実行されませんecho "これはテストです
";
?>
上記の例では次のエラーが発生し、プログラムは実行を続行できません。
致命的なエラー: 未定義メソッド Test::demo() の呼び出し
次に「__call()」メソッドを追加します。このメソッドには 2 つのパラメータがあります。最初のパラメータは、存在しないメソッドを呼び出す処理です。 __call() メソッドが自動的に呼び出されるとき、存在しないメソッド名が最初のパラメーターに渡され、2 番目のパラメーターはこのメソッドの名前になります
パラメータは配列として渡されます。
//これはテストクラスであり、属性やメソッドはありませんクラステスト{
//存在しないメソッドを呼び出すときに自動的に呼び出されるメソッド。最初のパラメータはメソッド名、2 番目のパラメータは配列パラメータです。function __call($function_name, $args){
print "呼び出した関数: $function_name(parameters:";print_r($args);print ") は存在しません!n";
}
}?>//Testクラスのオブジェクトを生成$test=新しいテスト();//オブジェクトに存在しないメソッドを呼び出す$test->demo("1", "two", "three");//プログラムは終了せず、ここで実行できますecho "これはテストです";
上記の例の出力結果は次のとおりです:
実行結果
呼び出した関数: デモ (パラメーター: Array ( [0] => one [1] => two [2] => three ) ) は存在しません!
これはテストです。
11. 抽象メソッドと抽象クラス OOP 言語では、クラスは 1 つ以上のサブクラスを持つことができ、各クラスには外部コードとして少なくとも 1 つのパブリック メソッドがあります
そのインターフェイスにアクセスします。抽象メソッドは継承を容易にするために導入されました。まず、抽象クラスと抽象メソッドの定義を見てみましょう。 使い方をもう一度説明します。
抽象メソッドとは何ですか? メソッド本体のないクラスで定義したメソッドは抽象メソッドです
いわゆるノーメソッド本体とは、
を指します。 メソッドを宣言するとき、中括弧やその内部のコンテンツはありません。
代わりに、宣言時にメソッド名の後に直接セミコロンを追加します。
さらに、抽象メソッドを宣言する場合は、キーワード「abstract」を追加して変更します。
例:
抽象関数 fun1();
抽象関数 fun2();
上記の例は、メソッド本体が「abstract」で変更されていない抽象メソッド「fun1()」と「fun2()」です
抽象メソッドの後にセミコロンがあることを忘れないでください。クラス内に抽象メソッドであるメソッドがあれば、これになります。 各クラスは抽象クラスとして定義する必要があり、抽象クラスも、抽象クラス内の「abstract」キーワードで変更する必要があります。
オブジェクト メソッドとメンバー属性。ただし、1 つのメソッドが抽象である限り、クラスは
を使用して抽象クラスとして宣言する必要があります。 「abstract」を変更します。
例:
コードスニペット
抽象クラスのデモ
{
var $test;抽象関数 fun1();抽象関数 fun2();関数 fun3(){
....
}
}
上記の例では、抽象クラス「Demo」を定義し、「abstract」で変更し、このクラスにメンバーを定義しています
属性「$test」、2 つの抽象メソッド「fun1」および「fun2」、および非抽象メソッド fun3()、次に抽象クラス I
; どのように使用するのでしょうか? 最も重要な点は、抽象クラスはインスタンス オブジェクトを生成できないため、これを何度も行ってきました
。 前述したように、クラスを直接使用することはできません。クラスを通じてインスタンス化されたオブジェクトを使用しているため、抽象クラスはインスタンス オブジェクトを生成できません。 抽象クラスを宣言することは何に役立ちますか? 抽象クラスを定義することは
と同等です。 サブクラスが準拠することを要求する仕様が定義されている場合、サブクラスが抽象クラスを継承した後は、抽象クラス内の抽象メソッドに従う必要があります
サブクラスを実装する必要があります。サブクラスは、親クラスのすべての抽象メソッドを実装する必要があります。そうでない場合は、サブクラスにまだ抽象メソッドが存在し、その後、サブクラスが クラスはまだ抽象クラスであり、インスタンス化することはできません。なぜ、抽象クラスから継承する必要があるのでしょうか? 場合によっては、それを実装する必要があるからです。 一部の関数は抽象クラスから継承する必要があります。そうしないと、これらの関数を実装できなくなります。抽象クラスを継承する場合は、それを実装する必要があります
。 抽象メソッド;
コードスニペット
抽象クラスのデモ
{
var $test;
抽象関数 fun1();抽象関数 fun2();関数 fun3(){
....
}
{}$demo=new Demo(); //抽象クラスはインスタンス オブジェクトを生成できるため、インスタンス化されたオブジェクトがサブクラスに渡されるのは間違いです。 クラステストはデモを拡張します
{
関数 fun1()
...
関数 fun2()}
{...
}
}12.php5インターフェース技術 PHP は、ほとんどのオブジェクト指向プログラミング言語と同様、多重継承をサポートしていません。つまり、各クラスは 1 つの親クラスのみを継承できます。 この問題を解決するために、PHP はインターフェースを導入しました。インターフェースの考え方は、インターフェースを実装するクラスが実装しなければならない一連のものを指定することです。 方法。インターフェイスは特別な抽象クラスであり、抽象クラスは特別なクラスなので、インターフェイスも特別なクラスです。なぜ$test=new Test(); //親クラスのすべての抽象メソッドが実装されているため、サブクラスはオブジェクトをインスタンス化できます?> fun3 は再実装せずに適用可能
インターフェースが特別な抽象クラスであると言うのはどうでしょうか? 抽象クラス内のすべてのメソッドが抽象メソッドである場合は、それを変更しましょう
最初の宣言メソッドは「インターフェイス」を使用します。つまり、インターフェイス内のすべてのメソッドは抽象メソッドとして宣言される必要があります。 変数は宣言できず、インターフェイス内のすべてのメンバーはパブリック権限を持っています。したがって、サブクラスも実装時に
を使用する必要があります。 パブリック権限を使用します。クラスを宣言するときに使用するキーワードは「class」、インターフェイスは特別なクラス、使用されるキーワードは
"インターフェイス";
クラス定義: クラス クラス名 { ... }、インターフェイス宣言: インターフェイス インターフェイス名 { ... } コードスニペット
//interface キーワードを使用してインターフェイスを定義します。「One」はインターフェイス名ですインターフェース 1{
//定数を定義するconst 定数 = '定数値';//抽象メソッド「fun1」を定義するパブリック関数 fun1();//抽象メソッド「fun2」を定義パブリック関数 fun2();
}
?> 上記の例では、インターフェイス「one」が定義されており、2 つの抽象メソッド「fun1」と「fun2」を宣言しています。 上記のメソッドはすべて抽象メソッドなので、抽象メソッドを宣言するときに、This
のような「abstract」を使用する必要はありません。 キーワード、このキーワードはデフォルトで追加されており、インターフェースの「パブリック」アクセス許可を削除することもできます、 デフォルトはパブリックであり、インターフェイス内のすべてのメンバーはパブリックである必要があるため、インターフェイス内のメンバーは気にしません。 「プライベート」および「保護された」アクセス許可を使用できる場合は、パブリックまたはデフォルトを使用する必要があります。さらに、インターフェイスでは、 定数「constant」も宣言しました
変数メンバーはインターフェイスでは使用できないため、 const を使用する必要があります
キーワード宣言。
インターフェイスは特別な抽象クラスであり、その中のすべてのメソッドは抽象メソッドであるため、インターフェイスはインスタンス オブジェクトを生成できません。
また、すべての抽象メソッドはサブクラスで実装する必要があるという仕様としても機能します。
「extends」キーワードを使用すると、あるインターフェイスが別のインターフェイスを継承できるようになります。
コードスニペット
//別のインターフェースを継承するには「extends」を使用しますインターフェース 2 が 1 を拡張{
関数 fun3();関数 fun4();
}
?> インターフェースのサブクラスを定義してインターフェース内のすべての抽象メソッドを実装する場合、使用されるキーワードは
ではなく「implements」です。 それは、先ほど述べた「拡張」です。
コードスニペット
//「implements」キーワードを使用して、インターフェースに抽象メソッドを実装しますクラス 3 は 1 を実装します{
関数 fun1(){
....
}
関数 fun2(){
....
}
}//すべてのメソッドが実装されたら、サブクラスを使用してオブジェクトをインスタンス化できます。$three=新しい Three();
?>
抽象クラスを使用してインターフェースにいくつかの抽象メソッドを実装することもできますが、オブジェクトをインスタンス化するには、この抽象クラスには
が必要です サブクラスがそのすべての抽象メソッドを実装している場合のみ;
前に述べたように、PHP は単一継承です。クラスは親クラスを 1 つだけ持つことができますが、クラスは複数のインターフェースを実装できます。 それは、私たちが学校にいる場合、国の法律だけでなく、学校の法律も遵守しなければならないのと同じように、クラスが複数の規範を遵守しなければならないのと同じです
校則も同じです
コードスニペット
//implements を使用して複数のインターフェースを実装するクラス 4 つの実装インターフェース 1、インターフェース 2、... 。{
// オブジェクトをインスタンス化する前に、インターフェイス内のすべてのメソッドを実装する必要があります。
}?>
PHP では、クラスが複数のインターフェースを実装できるだけでなく、クラスを継承するときに複数のインターフェースを実装することもできます。 クラスを継承してからインターフェイスを実装します。//extends を使用してクラスを継承し、implements を使用して複数のインターフェイスを実装します
class Four は、クラス名 1 を拡張し、インターフェイス 1、インターフェイス 2、... を実装します。{// オブジェクトをインスタンス化する前に、インターフェイス内のすべてのメソッドを実装する必要があります... ... ... ... ..}?> 抽象クラスでは、抽象メソッドの存在が許可されますが、非抽象メソッドの存在も許可されます。インターフェイスでは、抽象メソッドと定数のみが存在できます。したがって、抽象メソッドはインターフェイスを通じて継承および実装でき、抽象メソッド内の非抽象メソッドは self:: メソッド名を通じて呼び出されます。 例: //抽象クラスはインターフェースクラスを継承し、インターフェースクラスのメソッドを実装します抽象クラスのデモは 1 つを実装します{ var $test;
抽象関数 fun1();
抽象関数 fun2();
関数 fun3(){
echo 「デモ授業は楽しいですよ
」";
//抽象クラスのメソッド間で相互に呼び出しするには、self
を使用します self::fun4();
}
//抽象クラスのインターフェース、または抽象クラスを継承する特定のサブクラスにメソッドを実装します
関数 fun4(){
echo "これはデモクラスの fun4
";
}
}
//インターフェース
インターフェース 1{
パブリック関数 fun4();
}
//抽象クラスを継承
クラステストはデモを拡張します{
//抽象クラスのメソッドをオーバーライドします
関数 fun1(){
echo "これはテストクラスで楽しい1
";
}
関数 fun2(){
echo "これはテストクラスの楽しい 2 ";
}
//fun3を書き換えなければ、呼び出し時に親クラスのfun3が自動的に呼び出されます
関数 fun3(){
エコー「こんにちは
」";
//親クラスのメソッドを呼び出します
親::fun3();
}
関数 fun4(){
エコー「こんにちは、こんにちは!」;
}
}
$p1 = 新しいテスト();
$p1->fun1();
$p1->fun2();
$p1->fun3();
?> 操作結果: これはテストクラスで楽しいです 1
テストクラスの楽しい2
です こんにちは
デモクラスでは楽しい3
です デモクラスのfun4
です こんにちはこんにちは!
13. ポリモーフィックなアプリケーション 私の個人的な意見では、ポリモーフィズムはカプセル化と継承に加えてオブジェクト指向の 3 つの主要な機能の 1 つであり、PHP で実現できると考えています
。 ポリモーフィズムですが、C++やJavaなどのオブジェクト指向言語と比べると、PHP自体がポリモーフィズムであるため、それほど顕著ではありません。 弱い型付け言語なので、親クラス オブジェクトをサブクラス オブジェクトに変換したり、サブクラス オブジェクトを親クラス オブジェクトに変換したりする問題がないため、多くの
ポリモーフィズムの適用はそれほど明白ではありません。いわゆるポリモーフィズムとは、パブリック
などで複数の種類のオブジェクトを処理できるプログラムの機能を指します。 会社で働く場合、財務部門は毎月、同じ給与支払い方法を社内のさまざまな従業員またはさまざまな役職の従業員に適用します。 すべてこの方法で支払われますが、支払われる賃金は異なります。したがって、賃金を支払う方法は複数あります
形状。
オブジェクト指向プログラムの場合、ポリモーフィズムは、サブクラス オブジェクトを親クラス参照に割り当ててから、親クラスのメソッドを呼び出して
サブクラスが親クラス(基本クラス:class A{})をオーバーライドするメソッドを実行しますが、PHPでは弱く型付けされており、親クラスの参照に関係なくオブジェクト参照が同じであるか、
サブクラス参照。 次に例を見てみましょう。まず、ポリモーフィズムを使用するには、親クラス オブジェクトとサブクラス オブジェクトの間に関係が必要です。形を作ります
インターフェイスまたは抽象クラスは、親クラスとして使用されます。その中には 2 つの抽象メソッドがあり、1 つは境界を見つけるもので、もう 1 つは領域を見つけるものです。 このインターフェースのサブクラスにはさまざまな形状があり、それぞれの形状には周囲と面積があり、親クラスがインターフェースであるため、サブクラス
親クラスの perimeter と area の 2 つの抽象メソッドを実装する必要があります。これの目的は、異なる形状の各サブクラスが確実に従うようにすることです。 親クラスのインターフェースの仕様により、周囲長と面積を計算するメソッドが必要です。コードスニペット
// サブクラスが実装するための 2 つの抽象メソッドを含むシェイプ インターフェイスを定義します。インターフェース形状{関数エリア();関数perimeter();}// 形状インターフェイスの周囲と面積を実装するための長方形のサブクラスを定義します。クラス Rect は Shape を実装します{プライベート $width;プライベート $height;関数 __construct($width, $height){$this->width=$width;$this->高さ=$高さ;}関数エリア(){return "長方形の面積は次のとおりです。".($this->width*$this->height);}関数perimeter(){return "長方形の周囲長は次のとおりです:".(2*($this->width+$this->height));}}// 円のサブクラスを定義して、形状インターフェイスの周囲と面積を実装します。クラス Circular は Shape を実装します{プライベート $radius;関数 __construct($radius){$this->radius=$radius;}関数エリア(){return "円の面積は次のとおりです。".(3.14*$this->radius*$this->radius);}関数perimeter(){return "円の円周は次のとおりです。".(2*3.14*$this->radius);}}// サブクラスの四角形オブジェクトを形状の参照に代入します$shape=new Rect(5, 10);echo $shape->area()."
";echo $shape->perimeter()."
";// サブクラスの円オブジェクトをシェイプの参照に代入します$shape=新しい円形(10);echo $shape->area()."
";echo $shape->perimeter()."
";?>
上記例の実行結果:
実行結果
長方形の面積は: 50
長方形の周囲長は: 30
円の面積は: 314
円周は: 62.8
上記の例から、長方形オブジェクトと円形オブジェクトがそれぞれ変数 $shape に代入され、$shape 参照内の領域が呼び出されることがわかります
境界法を使用すると、異なる結果が表示されます。これはポリモーフィックなアプリケーションです。実際、弱く型付けされた PHP では、
に直面しています。 象の言語では、ポリモーフィズムの機能は特に明確ではありません。実際には、オブジェクト型変数の変数適用です。
14. オブジェクトをシリアル化します
場合によっては、オブジェクトをネットワーク経由で送信する必要がある場合、送信を容易にするために、オブジェクト全体をバイナリ文字列に変換して
まで待つことができます。 反対側に到達すると、元のオブジェクトに復元されます。このプロセスは、シリアル化と呼ばれます。、ちょうど車に車輪を通すときと同じです。 米国に発送する場合、車は比較的大きいため、車を小さなパーツに分解し、これらのパーツを通過させます
船で米国に輸送され、その後部品が組み立てられて車に戻されます。
オブジェクトをシリアル化する必要がある状況は 2 つあります。1 つ目の状況は、ネットワーク経由でオブジェクトを送信するときにオブジェクトをシリアル化する必要があることです
。 シリアル化。2 番目のケースは、ファイルまたはデータベースにオブジェクトを書き込むときにシリアル化を使用することです。
シリアル化には 2 つのプロセスがあり、1 つはオブジェクトをバイナリ文字列に変換するシリアル化です
。 オブジェクトをシリアル化する関数と、オブジェクトから変換されたバイナリ文字列をオブジェクトに変換する逆シリアル化関数です。 unserialize() 関数を使用してオブジェクトを逆シリアル化します。
PHPのserialize()関数のパラメータはオブジェクト名であり、戻り値は文字列です。Serialize()によって返される文字列には
が含まれます。 意味は曖昧です。通常、オブジェクト情報を取得するためにこの文字列を解析することはありません。返された文字列をネットワークの別の部分に渡すだけです。 終了するか、キューブに保存します。
PHP の unserialize() 関数は、オブジェクトを逆シリアル化するために使用されます。この関数のパラメーターは、serialize() 関数の戻り値
です。 もちろん、出力は再編成されたオブジェクトです。クラスの人{//メンバーの属性は以下の通りですvar $name //人の名前var $sex //人の性別var $age //人の年齢;//属性名 $name、性別 $sex、年齢 $age に値を割り当てるコンストラクター パラメーターを定義します関数 __construct($name="", $sex="", $age=""){コードスニペット$this->name=$name;$this->sex=$sex;$this->age=$age;}//この人の話し方、自分の属性を表現する方法関数say(){echo "私の名前は:".$this->name." 性別:".$this->性別" 私の年齢:".$this->age."
";}}$p1=新しい人("張三"、"男性"、20歳);$p1_string=serialize($p1); //オブジェクトをシリアル化し、文字列を返しますecho $p1_string."
" //通常はシリアル化された文字列を解析しません$p2=unserialize($p1_string); //シリアル化された文字列をオブジェクト $p2 にデシリアライズします$p2->say();?> 実行結果
O:6:"人物":3:{s:4:"名前";s:4:"張三";s:3:"性別";s:2:"男性";s:3:"年齢";i:20;}
私の名前:Zhang San 性別:男性 私の年齢:20
php5 には __sleep() メソッドと __wakeup() メソッドという 2 つのマジック メソッドがあり、オブジェクトがシリアル化されると 1 つが呼び出されます。 __sleep() メソッドは、就寝前にいくつかの作業を完了し、再び起きたときに、つまりバイナリ文字列からオブジェクトを再形成するために使用されます。 次に、PHP の別の関数 __wakeup() が自動的に呼び出され、オブジェクトが起動時に実行するいくつかのアクションが実行されます。
__sleep() 関数はパラメータを受け入れませんが、シリアル化する必要があるプロパティを含む配列を返します。含まれていません
__sleep() メソッドを使用しないと、PHP はすべての属性を保存します。コードスニペット
クラス人{//以下はその人のメンバー属性ですvar $name //人の名前;var $sex //人の性別;var $age // 人の年齢;//属性名 $name、性別 $sex、年齢 $age に値を割り当てるコンストラクター パラメーターを定義します。function __construct($name="", $sex="", $age=""){$this->name=$name;$this->sex=$sex;$this->age=$age;}//この人の話し方で、自分の属性がわかる関数say(){echo "私の名前は:".$this->name." 性別: ".$this->性別" 私の年齢: ".$this->age."
";}//シリアル化を指定する場合、配列にない属性 $sex を無視して、返された配列内の $name と $age の値をシリアル化します。関数 __sleep(){$arr=array("名前", "年齢");リターン($arr);}
// オブジェクトを再生成するとき、$age を 40 に再割り当てします関数 __wakeup() {$this->年齢 = 40;}}$p1=新しい人("張三", "男性", 20);// オブジェクトをシリアル化し、文字列を返し、__sleep() メソッドを呼び出し、配列にない属性 $sex を無視します$p1_string=シリアル化($p1);echo $p1_string."
" // 通常、シリアル化された文字列は解析されません。$p2=unserialize($p1_string); // 形成されたオブジェクト $p2 を逆シリアル化し、$age を 40 に再割り当てします$p2->say();?>
上記の例の出力値は次のとおりです:
実行結果
O:6:"人物":2:{s:4:"名前";s:4:"張三";s:3:"年齢";i:20;} 私の名前:Zhang San 性別:私の年齢:40
15. クラスを自動的にロードする
多くの開発者がオブジェクト指向アプリケーションを作成する場合、クラス定義ごとに PHP ソース ファイルを作成します。大迷惑
面倒なのは、各スクリプトの先頭にインクルード ファイルの長いリスト (クラスごとに 1 つのファイル) を書かなければならないことです。
ソフトウェア開発システムにおいて、調整が必要な場合、すべてのクラスをPHPファイルに記述することは不可能です。 別のファイルで宣言されたクラスを使用する場合は、このファイルを include で導入する必要があります。ただし、ファイルが大量にある場合もあります
プロジェクトに必要なクラスファイルを一つ一つインクルードするのは面倒なので、また使ってみませんか
このクラスが配置されている PHP ファイルにどのようなクラスをインポートする必要がありますか? これが、ここで説明する自動読み込みクラスです。
PHP 5 では、まだ定義されていないクラスを使用しようとすると自動的に呼び出される __autoload() 関数を定義できます
この関数を呼び出すことで、スクリプト エンジンは、PHP が __autoload() 関数
で失敗する前に、必要なクラスをロードする最後のチャンスを得ることができます。 数値によって受け取られるパラメータの 1 つは、ロードするクラスのクラス名です。そのため、プロジェクトに取り組んでいるとき、定義されたクラスのファイル名を整理するときに
する必要があります。 特定のルールに従って、クラス名を中心に置くことが最善です。または、
などの統一されたプレフィックスまたはサフィックスを追加してファイル名を形成することもできます。 xxx_classname.php、classname_xxx.php、classname.php など。
この例では、MyClass1.php ファイルと MyClass2.php ファイルからそれぞれ MyClass1 クラスと MyClass2 クラスをロードしようとします
コードスニペット
関数 __autoload($classname){require_once $classname .php';}//MyClass1 クラスは、パラメーター「MyClass1」を渡して、__autoload() 関数を自動的に呼び出しません。$obj = 新しい MyClass1();//MyClass2 クラスは、__autoload() 関数を自動的に呼び出してパラメータ「MyClass2」を渡しません。$obj2 = 新しい MyClass2();?>