>백엔드 개발 >PHP 튜토리얼 >PHP 객체 지향 - 오버로딩을 자세히 설명하는 샘플 코드

PHP 객체 지향 - 오버로딩을 자세히 설명하는 샘플 코드

黄舟
黄舟원래의
2017-03-25 10:07:151375검색

오버로딩

PHP의 "오버로딩"은 모두 동일한 명사를 사용한다는 점을 제외하면 대부분의 다른 객체 지향 언어와 다릅니다. 전통적인 "오버로딩"은 동일한 이름을 가진 여러 클래스 메서드를 제공하는 데 사용되지만 각 메서드에는 매개 변수 유형과 번호가 다릅니다. PHP에서 제공하는 "오버로딩"은 클래스 속성과 메서드를 동적으로 "생성"하는 것을 의미합니다. 오버로드된 메서드는 현재 환경에서 정의되지 않은 또는 보이지 않는 클래스 특성이나 메서드를 호출할 때 호출됩니다. 그것은 마법의 방법을 통해 달성됩니다.
일반적으로 클래스의 모든 멤버 속성을 비공개로 정의하는 것이 현실적인 논리에 더 부합하고 클래스의 멤버를 더 잘 보호할 수 있습니다. 그러나 멤버 속성을 읽고 할당하는 작업은 매우 빈번하며, 개체 외부에서 얻고 할당할 수 있는 공용 메서드를 클래스의 각 전용 속성에 대해 정의하는 것은 매우 성가신 일입니다. 따라서 PHP 5.1.0 이후 버전에서는 "get()"과 "set()" 두 가지 메소드가 미리 정의되어 있는데, 이는 사용된 모든 프라이빗 속성에 값을 얻어 할당하고, 프라이빗 속성이 존재하는지 확인하는 데 사용됩니다. . 객체의 개인 속성을 삭제하는 데 사용되는 "isset()" 메서드와 "unset()" 메서드입니다.
일반인의 관점에서 보면, PHP에서 오버로드의 의미는 개체나 클래스가 정의되지 않거나 보이지 않는 속성과 메서드를 사용할 때 발생하는 "처리 메커니즘" 중 일부를 의미합니다.

속성 오버로딩

객체에 존재하지 않는 속성을 사용할 때 이 클래스에는 미리 설정된 대응책이 있다(처리 메커니즘) ).
 속성은 본질적으로 변수이며, 4개의 연산만 갖습니다:

값:

언제 속성이 존재하지 않는(정의되지 않거나 보이지 않는) 개체의 "검색"이 이루어지면 메서드가 자동으로 호출됩니다. GET() 메서드는 대소문자를 구분하지 않습니다.

할당:

객체에 존재하지 않는(정의되지 않거나 보이지 않음) 속성을 "할당"하면 자동으로 메서드 호출 : SET()

판단(isset):

객체의 속성이 존재하지 않을 때(undefine 또는 visible) isset을 만들 때 () 판단에 따라 메소드가 자동으로 호출됩니다: isset()

파괴(설정 해제):

객체가 더 이상 존재하지 않을 때 기존(정의되지 않았거나 보이지 않는) 속성은 unset()에 의해 판단되며, 메소드는 자동으로 호출됩니다: unset()

위의 네 가지 메소드를 매직 메소드라고 합니다.

마법의 방법

GET($property name):

객체의 존재하지 않는 속성에 대한 "값을 가져올 때" 자동으로 호출되는 메소드 이 메소드는 가져올 존재하지 않는 속성의 이름을 나타내는 형식 매개변수를 사용할 수 있습니다( 문자열). ) 이 방법을 사용하면 예상치 못한 상황에서 특별한 처리를 수행할 수 있습니다.

예:

<?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($속성 이름, 값):

객체의 존재하지 않는 속성을 "할당"하면 이 내부 매직 메서드가 자동으로 호출됩니다. 여기에는 존재하지 않는 "속성 이름"과 "속성 이름"을 각각 나타내는 두 개의 형식 매개변수가 있습니다. 속성이 할당됩니다.
_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($속성 이름):

객체에 존재하지 않는 속성에 대해 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 클래스가 선언됩니다. 모든 구성원 속성은 비공개로 설정됩니다. 두 개의 사용자 정의 "isset()" 및 "unset()" 메소드 를 클래스에 추가합니다. 이 두 메서드는 클래스 외부에서 "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 중국어 웹사이트의 기타 관련 기사를 참조하세요!

성명:
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.