zoukankan      html  css  js  c++  java
  • php面向对象之构造函数和析构函数

    php面向对象之构造函数和析构函数

    简介

    php面向对象支持两种形式的构造函数和析构函数,一种是和类同名的构造函数(php5.5之前),一类是魔术方法(php5.5之后)。与类名相同的构造函数优先级比魔术方法低。

    php有一类很神奇的方法,这些方法是保留方法,通常不会在外部被显式调用,他们使用双下划线(__)开头,他们被称为魔术方法(Magic Methods)。php官方也不建议定义其他双下划线开头的方法。

    这次介绍最常见的魔术方法:构造函数和析构函数。

    1. 构造函数(__construct)

    void __construct ([ mixed $args [, $... ]] )

    构造函数:拥有构造函数的类会在每次创建新对象时先调用此方法,所以非常适合在使用对象前做一些初始化服务。

    注意:

      1. clone并不会调用构造函数

      2. 如果子类定义了构造函数,则不会隐式调用父类的构造函数

      3. 子类的构造函数允许和父类的构造函数参数不一致

      4. 如果子类没有定义构造函数,php会尝试寻找父类的构造函数

      5. 如果父类没有定义构造函数,使用parent关键字显式调用父类构造函数,会导致致命错误

     1 <?php
     2 
     3 class P{
     4 
     5     public function __construct(){
     6         echo __CLASS__ . "
    ";
     7     }
     8 
     9 }
    10 
    11 class C1 extends P{
    12 
    13     public function __construct(){
    14         echo __CLASS__ . "
    ";
    15     }
    16 
    17 }
    18 
    19 class C2 extends P{
    20 
    21     public function __construct(){
    22         parent::__construct();
    23         echo __CLASS__ . "
    ";
    24     }
    25 
    26 }
    27 
    28 class C3 extends P{
    29 
    30 }
    31 
    32 // P
    33 $ins = new P();
    34 
    35 // Nothing
    36 $ins2 = clone $ins;
    37 
    38 // C1
    39 new C1();
    40 
    41 // P
    42 // C2
    43 new C2();
    44 
    45 // P
    46 new C3();

    除了魔术方法的构造函数,php还支持与类名相同的构造函数,不过优先级比魔术方法低:

     1 <?php
     2 
     3 class C1{
     4 
     5     public function C1(){
     6         echo __CLASS__ . "1
    ";
     7     }
     8 
     9     public function __construct(){
    10         echo __CLASS__ . "2
    ";
    11     }
    12 
    13 }
    14 
    15 class C2{
    16 
    17     public function C2(){
    18         echo __CLASS__ . "1
    ";
    19     }
    20 
    21 }
    22 
    23 class C3{
    24 
    25     public function C3(){
    26         echo __CLASS__ . "1
    ";
    27     }
    28 
    29     public function __construct(){
    30         echo __CLASS__ . "2
    ";
    31         $this->C3();
    32     }
    33 
    34 }
    35 
    36 // C12
    37 new C1();
    38 
    39 // C21
    40 new C2();
    41 
    42 // C32
    43 // C31
    44 new C3();

    php5.3.3之后,在命名空间之内使用与类名同名的方法,不再作为构造函数,命名空间之外不变:

     1 <?php
     2 
     3 namespace N;
     4 
     5 class C{
     6 
     7     public function C(){
     8         echo __CLASS__ . "
    ";
     9     }   
    10 
    11 }
    12 
    13 // Nothing
    14 new NC();

    构造函数可以用全部三个访问控制修饰符,如单例模式:

     1 <?php
     2 
     3 class Single{
     4 
     5     public static function getInstance(){
     6         static $ins = null;
     7         if(empty($ins)){
     8             $ins = new self();
     9         }   
    10         return $ins;
    11     }   
    12 
    13     private function __construct(){
    14         echo __CLASS__ . "
    ";
    15     }   
    16 
    17 }
    18 
    19 // Single
    20 Single::getInstance();

    2. 析构函数(__destruct)

    void __destruct ( void )

    析构函数:析构函数会在某个对象的引用被全部删除或对象被显示销毁时执行。

    注意:

      1. 同构造函数类似,父类的析构函数并不会被引擎暗中调用,必须显式调用parent::__destruct

      2. exit和die并不能阻止析构函数的执行

      3. 致命错误会阻止析构函数的执行

      4. 在析构函数中调用exit,可以阻止其他未执行的析构函数的执行

      5. 如果父类没有定义析构函数,使用parent关键字显式调用父类析构函数,会导致致命错误

    <?php
    
    class P{
    
        function __destruct(){
            echo get_class($this) . "	" . __CLASS__ . "
    ";
        }   
    }
    
    class C1 extends P{
    
        function __destruct(){
            echo get_class($this) . "	" . __CLASS__ . "
    ";
        }   
    
    }
    
    class C2 extends P{
    
        function __destruct(){
            parent::__destruct();
            echo get_class($this) . "	" . __CLASS__ . "
    ";
        }   
    
    }
    
    class C3 extends P{
    
    }
    
    $insP = new P();
    $ins1 = new C1();
    $ins2 = new C2();
    $ins3 = new C3();
    
    /**
    输出:
    C3    P
    C2    P
    C2    C2
    C1    C1
    P    P
    **/

    代码

     1 <?php
     2 /*php5.5以后用这个魔术常量来写我们的构造函数
     3 function __constrct([参数列表]){
     4 
     5 方法体//通常用来对成员属性进行初始化赋值
     6 
     7 }
     8  * */
     9 class Person{
    10     public $userName;
    11     public $age;
    12 
    13     function __construct($userName,$age){
    14         echo '我是构造函数,我在new对象的时候会被调用';
    15         $this->userName = $userName;
    16         $this->age = $age;
    17     }
    18     function __destruct(){
    19         echo '我是析构函数,我在对象被销毁的时候调用';
    20     }
    21 }
    22 // $p = new Person();
    23 $p = new Person("Clive", 27);
    24 echo '<hr/>';
    25 echo $p->age;
    26 echo '<hr/>';
    27 echo $p->userName;
    28 $p = null;
    29 
    30 /*析构函数
    31  * function __destruct() {
    32 
    33 }
    34  *
    35  * */

    23、构造函数在new对象的时候调用,23行,系统自动调用

    28、析构函数在对象已经没有引用的时候调用,比如28行,系统自动调用

  • 相关阅读:
    RedHat Linux-配置YUM仓库
    04、管道符、重定向与环境变量
    03、新手必须掌握的Linux命令
    size_t
    decltype关键字
    python numpy使用笔记
    Huffman编码
    动态规划(dynamic programming)
    Prim算法
    Kruskal算法
  • 原文地址:https://www.cnblogs.com/Renyi-Fan/p/8546665.html
Copyright © 2011-2022 走看看