ホームページ > バックエンド開発 > PHPチュートリアル > PHP オブジェクト指向 - オーバーロードの詳細を示すサンプル コード

PHP オブジェクト指向 - オーバーロードの詳細を示すサンプル コード

黄舟
リリース: 2023-03-06 21:56:02
オリジナル
1376 人が閲覧しました

オーバーロード

PHPの「オーバーロード」は、すべて同じ名詞を使用することを除いて、他のほとんどのオブジェクト指向言語とは異なります。従来の「オーバーロード」は、同じ名前を持つ複数のクラス メソッドを提供するために使用されますが、各メソッドのパラメーターの型と数は異なります。 PHP が提供する「オーバーロード」とは、クラスのプロパティとメソッドを動的に「作成」することを指します。オーバーロードされたメソッドは、現在の環境で未定義または不可視であるクラス属性またはメソッドを呼び出すときに呼び出されます。それは魔法の方法によって達成されます。
一般的に言えば、クラス内のすべてのメンバー属性をプライベートとして定義する方が現実的なロジックに沿っており、クラス内のメンバーをより適切に保護できます。ただし、メンバー プロパティへの読み取りと割り当ての操作は非常に頻繁に行われるため、オブジェクトの外部で取得して割り当てることができるパブリック メソッドをクラス内のプライベート プロパティごとに定義するのは非常に面倒です。したがって、PHP 5.1.0以降のバージョンでは、使用されるすべてのプライベート属性を取得して値を代入し、プライベート属性が存在するかどうかを確認するために使用される2つのメソッド「get()」と「set()」が事前定義されています。オブジェクト内のプライベート プロパティを削除するために使用されるメソッド「isset()」とメソッド「unset()」。
平たく言えば、PHPにおけるオーバーロードの意味は、オブジェクトやクラスがその未定義または目に見えないプロパティやメソッドを使用するときの「処理メカニズム」の一部を指します。

属性のオーバーロード

オブジェクトに存在しない属性を使用する場合、このクラスには事前に対策(処理機構)が設定されています。
属性は本質的には 変数 であり、操作は 4 つだけです:

Value:

オブジェクトの存在しない (未定義または非表示) 属性の「値を取得」するとき、自動的に呼び出します。メソッド: GET() メソッドでは大文字と小文字が区別されません。

代入:

オブジェクトに存在しない(未定義または不可視)プロパティを「代入」する場合、メソッドが自動的に呼び出されます: SET()

Judgement (isset):

isset()がオブジェクトの存在しない(未定義または不可視)プロパティで判断された場合、メソッドが自動的に呼び出されます: isset()

Destruction (unset):

When the object's non -existent (未定義または非表示) 属性は unset() によって判断され、メソッドが自動的に呼び出されます: unset()

上記 4 つのメソッドはマジック メソッドと呼ばれます。

マジックメソッド

GET($プロパティ名):

オブジェクトに存在しないプロパティの「値を取得する」ときに自動的に呼び出されるメソッドです。 Bring 評価されるが存在しない属性の名前を表す仮パラメータ (string) このメソッドを使用すると、予期しない状況に対する特別な処理を実行できます。

例:

<?phpclass A{
    public  $p1 = 1;
}$a1 = new A();echo $a1->p1;  //1echo $a1->p2;	//未定义$p2,会报错, Notice: Undefined property: A::$p2?>
ログイン後にコピー

phpのオーバーロードでは、get()メソッドを使用して上記のエラーを「エレガントに処理」します。

<?php<?phpclass A{
    public  $p1 = 1;    
    //private $p2 = 1;  
    //这里将属性私有化,其实和未定义一样,对外部来说都相当于不存在

    function get($prop_name){

        /*
        //比如可以这样处理
        echo "<br />{$prop_name}属性还未定义(不存在)!";
        return "";  //也可以返回0,或false等
        */

        //还可以这样处理
        trigger_error("发生错误:属性不存在!", E_USER_ERROR);        
        die();
    }
}$a1 = new A();echo $a1->p1;  //1echo $a1->p2;	//未定义$p2,但经过"处理"?>
ログイン後にコピー

以下は、使用されるプライベートプロパティを取得する操作の例です。

例:

<?phpclass Person{
    public $name;  
    public $sex;    
    private $age;  //年龄私有化,类外不能直接访问这个属性    

    function construct($name=&#39;&#39;, $sex=&#39;&#39;, $age){
        $this->name = $name;        
        $this->sex = $sex;        
        $this->age = $age;   
    }    private function get($propertyName){ //这里要用private修饰,防止类外部调用
        if($propertyName == &#39;age&#39;){            
        return $this->age;
        }
    }
}$p = new Person(&#39;yeoman&#39;, &#39;男&#39;,23);
$v1 = $p->name;$v2 = $p->sex;$v3 = $p->age;    
//自动调用了get()方法获取私有属性age(函数定义里面返回)
echo "name=$v1, sex=$v2, age=$v3";?>
ログイン後にコピー

実行結果は以下の通り:

name=yeoman, sex=男, age=23
ログイン後にコピー

SET ($property name, value):

オブジェクトの存在しない属性が「割り当て」られると、この内部関数は自動的にMagicを呼び出すメソッドには、存在しない属性が割り当てられる「属性名」と「属性値」を表す 2 つの仮パラメータがあります。
このメソッドを _GET メソッドと組み合わせると、多くの場合、定義したクラスの拡張性が高まります。つまり、クラスまたはオブジェクトの属性をより便利に、より自由に使用できるようになります。

例:

<?phpclass A{
    //定义一个属性,
    protected $prop_list = array();    
    //初始为空数组

    //这个方法会在A的对象使用一个不存在的属性进行赋值时调用
    function set($p,$v){
        //echo "使用不存在的属性!";
        $this->prop_list[$p] = $v;     
    }    function get($p){
        return $this->prop_list[$p];    
    }
}$a1 = new A();$a1->p1 = 1;   
//不存在的属性名赋值,此时会调用_set(),并传过去"p1"和1$a1->p2 = 2;$a1->ac = &#39;avc&#39;;
echo "<br />输出这些“不存在的属性”的值:";
echo "<br />a1->p1:" . $a1->p1;    
//不存在的属性名取值,此时会调用_get(),并传过去"p1"echo "<br />a1->p2:" . $a1->p2;echo "<br />a1->ac:" . $a1->ac;?>
ログイン後にコピー

実行結果は以下の通り:

输出这些“不存在的属性”的值:a1->p1:1a1->p2:2a1->ac:avc
ログイン後にコピー

ISSET($property name):

isset()がオブジェクトに存在しない属性と判定された場合、内部メソッド: isset自動的に呼び出されます ();

使用法:

$v1 = isset($对象->不存在的属性);    //此时会调用这个对象所属类中的魔术方法:isset()
ログイン後にコピー

例:

<?phpclass A{
    //定义一个属性,
    protected $prop_list = array();    //初始为空数组

    //这个方法会在A的对象使用一个不存在的属性进行赋值时调用
    function set($p,$v){
        //echo "使用不存在的属性!";
        $this->prop_list[$p] = $v;     
    }    function get($p){
        if($this->prop_list[$p]){            return $this->prop_list[$p];
        }else{            return "该属性不存在!";
        }
    }    function isset($prop){   //isset()是自定义的方法, isset()是系统函数
        $re = isset($this->prop_list[$prop]);        return $re;
    }
}
$a1 = new A();
$a1->p1 = 1;//不存在的属性名赋值,此时会调用_set(),并传过去"p1"和1
$a1->p2 = 2;
$a1->ac = &#39;avc&#39;;
echo "<br />输出这些“不存在的属性”的值";
echo "<br />a1->p1:" . $a1->p1;//不存在的属性名取值,此时会调用_get(),并传过去"p1"
echo "<br />a1->p2:" . $a1->p2;
echo "<br />a1->ac:" . $a1->ac;
//下面演示isset判断不存在的属性
$v1 = isset($a1->p1);  //存在
$v2 = isset($a1->ppp1);    //不存在
var_dump($v1);echo "<br />";
var_dump($v2);?>
ログイン後にコピー

実行結果:

输出这些“不存在的属性”的值
a1->p1:1a1->p2:2a1->ac:avc

boolean trueboolean false
ログイン後にコピー

UNSET($property name)

unset() を使用して、そうでないプロパティを破棄する場合オブジェクト内に存在すると、自動的に内部メソッド unset();

<?phpclass A{
    //定义一个属性,
    protected $prop_list = array();    
    //初始为空数组

    //这个方法会在A的对象使用一个不存在的属性进行赋值时调用
    function set($p,$v){
        //echo "使用不存在的属性!";
        $this->prop_list[$p] = $v;     
    }    function get($p){
        if($this->prop_list[$p]){            
        return $this->prop_list[$p];
        }else{            
        return "该属性不存在!";
        }
    }    function unset($prop){
        unset($this->prop_list[$prop]); 
    }
}$a1 = new A();
$a1->p1 = 1;//不存在的属性名赋值,此时会调用_set(),并传过去"p1"和1
echo "<br />a1->p1:" . $a1->p1;//不存在的属性名取值,此时会调用_get(),并传过去"p1"//下面演示unset销毁一个不存在的属性
unset($a1->p1);
echo "<br />a1->p1:" . $a1->p1;?>
ログイン後にコピー

が呼び出されます。 実行結果は次のようになります:

a1->p1:1a1->p1:该属性不存在!
ログイン後にコピー

次の例では、 Person クラスを宣言し、すべてのメンバー属性を private に設定します。カスタムの「isset()」と「unset()」の 2 つの メソッド をクラスに追加します。これら 2 つのメソッドは、クラス外で "isset()" および "unset()" 関数を使用するときに自動的に呼び出されます。コードは次のとおりです:

<?php
class Person{
    private $name; //此属性被封住
    private $sex;
    private $age;

    function __construct($name=&#39;&#39;, $sex=&#39;男&#39;, $age){
        $this->name = $name;
        $this->sex = $sex;
        $this->age = $age;  
    }

    private function __isset($propertyName){   //需要一个参数,是测定的私有属性的名称
        if($propertyName == &#39;name&#39;){
            return false;   //返回假,不允许在类外部测定name属性   
        }
        return isset($this->$propertyName);   //这里propertyName要加$符,因为这是参数,不是属性
    }                       

    private function __unset($propertyName){
        if($propertyName == &#39;name&#39;)
            return; //退出方法,不允许删除对象中的name属性
        unset($this->$propertyName);  //这里propertyName要加$符
    }

    public function say(){
        echo "名字:" . $this->name . ",性别:" . $this->sex . ",年龄:" . $this->age . "<br />"; 
    }

}

$person = new Person("yeoman", "男", 23);

var_dump(isset($person->name));    //输出bool(false),不允许测定name属性
var_dump(isset($person->sex)); //输出bool(true),存在sex私有属性
var_dump(isset($person->age)); //输出bool(true),存在age私有属性
var_dump(isset($person->id));  //输出bool(false),测定对象中不存在id属性

unset($person->name);  //删除私有属性name,但在 __unset()中不允许删除
unset($person->sex);   //删除对象中的私有属性sex,删除成功
unset($person->age);

$person->say();    //对象中的sex和age属性被删除,输出:名字:yeoman,性别:,年龄:
?>
ログイン後にコピー

実行結果:

boolean falseboolean trueboolean trueboolean false名字:yeoman,性别:,年龄:
ログイン後にコピー

方法重载

  当对一个对象不存在的实例方法进行“调用”时,会自动调用类中的call()这个魔术方法;
  当对一个类不存在的静态方法进行“调用”时,会自动调用类中的callstatic()这个魔术方法。

例子:直接调用不存在的方法

<?phpini_set(&#39;display_errors&#39;,1);class A{}$a = new A();$a->f1();  //不存在的方法?>
ログイン後にコピー

  会报错,报错内容为:

Fatal error: Uncaught Error: Call to undefined method A::f1()
ログイン後にコピー

  对上面报错作“优雅处理”:

<?phpclass A{
    //当对这个类的对象不存在的实力方法进行调用时,会自动调用本方法
    //这个方法必须带2个形参:
    //$methodName:表示要调用的不存在的方法名;
    //$argument:表示要调用该不存在的方法时,所使用的实参数据,是一个数组。
    function call($methodName, $argument){
        //echo "call被调用了!";
        echo $methodName . "()方法不存在!";
    }
}$a = new A();$a->f1();  //不存在的方法,但经过处理?>
ログイン後にコピー

  运行结果为:

f1()方法不存在!
ログイン後にコピー

  当对一个类不存在的静态方法进行“调用”时,会自动调用类中的callstatic()这个魔术方法。和上面的处理类似。

以上がPHP オブジェクト指向 - オーバーロードの詳細を示すサンプル コードの詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

関連ラベル:
ソース:php.cn
このウェブサイトの声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。
最新の問題
人気のチュートリアル
詳細>
最新のダウンロード
詳細>
ウェブエフェクト
公式サイト
サイト素材
フロントエンドテンプレート