zoukankan      html  css  js  c++  java
  • 2017.8.05

    1、继承性extends

    继承性就是通过子类对已存在的父类进行功能扩展。单继承性,当父类成员改动时,继承他的子类也会随着变化。

    例子:

    <?php
        class Person {           //声明一个人类,定义人所具有的一些其本的属性和功能成员,做为父类 
            var $name;         //声明一个存储人的名子的成员
            var $sex;           //声明一个存储人的性别的成员
            var $age;           //声明一个存储人的年龄的成员
            
               function __construct($name="", $sex="男", $age=1) {    //构造方法用来创建对象并初使化成员属性
                $this->name = $name;           //为成员属性name在创建对象时赋初值
                $this->sex = $sex;              //为成员属性sex在创建对象时赋初值
                $this->age = $age;              //为成员属性age在创建对象时赋初值
            }
    
            function say(){           //在人类在声明一个通用的说话方法,介绍一下自己
                echo "我的名子叫:".$this->name.", 性别:".$this->sex.", 我的年龄是:".$this->age."。<br>";
            }    
            
            function run() {          //在人类是声明一个人的通用的走路方法
                echo $this->name."正在走路。<br>";
            }
        }
    
        class Student extends Person {   //声明一个学生类,使用extends关键字扩展(继承)Person类
            var $school;             //在学生类中声明一个所在学校school的成员属性
            
            function study() {        //在学生类中声明一个学生可以学习的方法
                echo $this->name."正在".$this->school."学习<br>";
            }    
        }
    
        class Teacher extends Student {  //再声明一个教师类,使用extends关键字扩展(继承)Student类
            var $wage;              //在教师类中声明一个教师工资wage的成员属性
            
            function teaching() {      //在教师类中声明一个教师可以教学的方法
                echo $this->name."正在".$this->school."教学,每月工资为".$this->wage."。<br>";    
            }
        }
        
        $teacher1=new Teacher("张三", "男", 40);   //使用继承过来的构造方法创建一个教师对象
        
        $teacher1->school="edu";        //将一个教师对象中的所在学校的成员属性school赋值
        $teacher1->wage=3000;         //将一个教师对象中的成员属性工资赋值
    
        $teacher1->say();              //调用教师对象中的说话方法
        $teacher1->study();            //调用教师对象中的学习方法
        $teacher1->teaching();          //调用教师对象中的教学方法
    ?>

    访问类型的控制修饰符private(只能在同一个类中进行访问),protected(可以在同一个类以及类的子类中访问),public(各个类中和所有外部成员中均可访问)。

    2、子类中重载父类的方法(相当于重写/修改父类中的方法)

    <?php
        class Person {           //声明一个人类,定义人所具有的一些其本的属性和功能成员,做为父类 
            protected $name;         //声明一个存储人的名子的成员
            protected $sex;           //声明一个存储人的性别的成员
            protected $age;           //声明一个存储人的年龄的成员
            
                function __construct($name="", $sex="男", $age=1) {  //构造方法用来创建对象并初使化成员属性
                $this->name = $name;           //为成员属性name在创建对象时赋初值
                $this->sex = $sex;              //为成员属性sex在创建对象时赋初值
                $this->age = $age;              //为成员属性age在创建对象时赋初值
            }
    
            function say(){           //在人类在声明一个通用的说话方法,介绍一下自己
                echo "我的名子叫:".$this->name.", 性别:".$this->sex.", 我的年龄是:".$this->age."。<br>";
            }    
        }
    
        class Student extends Person {   //声明一个学生类,使用extends关键字扩展(继承)Person类
            private $school;          //在学生类中声明一个所在学校school的成员属性
        
                 //覆盖父类中的构造方法,在参数列表中多添加一个学校属性,用来创建对象并初使化成员属性
                function __construct($name="", $sex="男", $age=1, $school="") {   
                //调用父类中被本方法覆盖的构造方法,从父类中继承过来的属性赋初值
                parent::__construct($name,$sex,$age);  
                $this->school=$school;      //新添一条为子类中新声明的成员属性赋初值
            }
    
            function study() {        //在学生类中声明一个学生可以学习的方法
                echo $this->name."正在".$this->school."学习<br>";
            }
            //定义一个和父类中同名的方法,将父类中的说话方法覆盖并重写,多说出所在的学校名称
            function say() { 
                parent::say();                         //parent::方法名;调用父类中被本方法覆盖掉的方法
                echo "在".$this->school."学校上学<br>";   //再原有的功能基础上多加一点功能
            }    
        }
    
        $student=new Student("张三","男",20, "edu");    //创建一个学生对象,并多传一个学校名称参数
        $student->say();                            //调用学生类中覆盖父类的说话方法
    ?>

    在子类中重写父类方法时,一定要高于或等于父类被覆盖的方法的访问权限。public>protected>private.

    3、PHP中的魔术方法(以下内容来自http://www.jb51.net/article/96167.htm)

    PHP中把以两个下划线__开头的方法称为魔术方法(Magic methods)。

    以下为常见的几种魔术方法:

    1、 __call(),在对象中调用一个不可访问方法时调用。

    该方法有两个参数,第一个参数 $function_name 会自动接收不存在的方法名,第二个 $arguments 则以数组的方式接收不存在方法的多个参数。

    1、 __call() 方法的格式:

    function __call(string $function_name, array $arguments)
    {
      // 方法体
    }

    2、 __call() 方法的作用:

    为了避免当调用的方法不存在时产生错误,而意外的导致程序中止,可以使用 __call() 方法来避免。

    该方法在调用的方法不存在时会自动调用,程序仍会继续执行下去。

    请参考如下代码:

    <?php
    class Person
    {              
      function say()
      {
                    
          echo "Hello, world!<br>";
      }  
         
      /**
       * 声明此方法用来处理调用对象中不存在的方法
       */
      function __call($funName, $arguments)
      {
         echo "你所调用的函数:" . $funName . "(参数:" ; // 输出调用不存在的方法名
         print_r($arguments); // 输出调用不存在的方法时的参数列表
         echo ")不存在!<br>
    "; // 结束换行          
      }                    
    }
    $Person = new Person();     
    $Person->run("teacher"); // 调用对象中不存在的方法,则自动调用了对象中的__call()方法
    $Person->eat("小明", "苹果");      
    $Person->say();

    运行结果:

    你所调用的函数:run(参数:Array ( [0] => teacher ) )不存在!

    你所调用的函数:eat(参数:Array ( [0] => 小明 [1] => 苹果 ) )不存在!

    Hello, world!

    2、 __get(),获得一个类的成员变量时调用

    在 php 面向对象编程中,类的成员属性被设定为 private 后,如果我们试图在外面调用它则会出现“不能访问某个私有属性”的错误。那么为了解决这个问题,我们可以使用魔术方法 __get()。

    魔术方法__get()的作用

    在程序运行过程中,通过它可以在对象的外部获取私有成员属性的值

    我们通过下面的 __get() 的实例来更进一步的连接它吧:

    <?php
    class Person
    {
      private $name;
      private $age;
     
      function __construct($name="", $age=1)
      {
        $this->name = $name;
        $this->age = $age;
      }
     
      /**
       * 在类中添加__get()方法,在直接获取属性值时自动调用一次,以属性名作为参数传入并处理
       * @param $propertyName
       *
       * @return int
       */
      public function __get($propertyName)
      { 
        if ($propertyName == "age") {
          if ($this->age > 30) {
            return $this->age - 10;
          } else {
            return $this->$propertyName;
          }
        } else {
          return $this->$propertyName;
        }
      }
    }
    $Person = new Person("小明", 60);  // 通过Person类实例化的对象,并通过构造方法为属性赋初值
    echo "姓名:" . $Person->name . "<br>";  // 直接访问私有属性name,自动调用了__get()方法可以间接获取
    echo "年龄:" . $Person->age . "<br>";  // 自动调用了__get()方法,根据对象本身的情况会返回不同的值

    运行结果:

    姓名:小明
    年龄:50

    3、 __set(),设置一个类的成员变量时调用

    __set( $property, $value )` 方法用来设置私有属性, 给一个未定义的属性赋值时,此方法会被触发,传递的参数是被设置的属性名和值。

    请看下面的演示代码:

    <?php
    class Person
    {
      private $name;
      private $age;
     
      public function __construct($name="", $age=25)
      {
        $this->name = $name;
        $this->age = $age;
      }
     
      /**
       * 声明魔术方法需要两个参数,真接为私有属性赋值时自动调用,并可以屏蔽一些非法赋值
       * @param $property
       * @param $value
       */
      public function __set($property, $value) {
        if ($property=="age")
        {
          if ($value > 150 || $value < 0) {
            return;
          }
        }
        $this->$property = $value;
      }
     
      /**
       * 在类中声明说话的方法,将所有的私有属性说出
       */
      public function say(){
        echo "我叫".$this->name.",今年".$this->age."岁了";
      }
    }
     
    $Person=new Person("小明", 25); //注意,初始值将被下面所改变
    //自动调用了__set()函数,将属性名name传给第一个参数,将属性值”小红”传给第二个参数
    $Person->name = "小红";   //赋值成功。如果没有__set(),则出错。
    //自动调用了__set()函数,将属性名age传给第一个参数,将属性值16传给第二个参数
    $Person->age = 16; //赋值成功
    $Person->age = 160; //160是一个非法值,赋值失效
    $Person->say(); //输出:我叫小红,今年16岁了

    运行结果:

    我叫小红,今年16岁了

    4、 __isset(),当对不可访问属性调用isset()或empty()时调用

    isset()是测定变量是否设定用的函数,传入一个变量作为参数,如果传入的变量存在则传回true,否则传回false。

    那么如果在一个对象外面使用isset()这个函数去测定对象里面的成员是否被设定可不可以用它呢?

    分两种情况,如果对象里面成员是公有的,我们就可以使用这个函数来测定成员属性,如果是私有的成员属性,这个函数就不起作用了,原因就是因为私有的被封装了,在外部不可见。

    那么我们就不可以在对象的外部使用isset()函数来测定私有成员属性是否被设定了呢?当然是可以的,但不是一成不变。你只要在类里面加上一个__isset()方法就可以了,当在类外部使用isset()函数来测定对象里面的私有成员是否被设定时,就会自动调用类里面的__isset()方法了帮我们完成这样的操作。

    __isset()的作用:当对不可访问属性调用 isset() 或 empty() 时,__isset() 会被调用。

    请看下面代码演示:

    <?php
    class Person
    {
      public $sex;
      private $name;
      private $age;
     
      public function __construct($name="", $age=25, $sex='男')
      {
        $this->name = $name;
        $this->age = $age;
        $this->sex = $sex;
      }
     
      /**
       * @param $content
       *
       * @return bool
       */
      public function __isset($content) {
        echo "当在类外部使用isset()函数测定私有成员{$content}时,自动调用<br>";
        echo isset($this->$content);
      }
    }
     
    $person = new Person("小明", 25); // 初始赋值
    echo isset($person->sex),"<br>";
    echo isset($person->name),"<br>";
    echo isset($person->age),"<br>";

    运行结果如下:

    1 // public 可以 isset()
    当在类外部使用isset()函数测定私有成员name时,自动调用 // __isset() 内 第一个echo
    1 // __isset() 内第二个echo
    当在类外部使用isset()函数测定私有成员age时,自动调用 // __isset() 内 第一个echo
    1 // __isset() 内第二个echo

    5、 __unset(),当对不可访问属性调用unset()时被调用。

    unset()这个函数的作用是删除指定的变量且传回true,参数为要删除的变量。

    那么如果在一个对象外部去删除对象内部的成员属性用unset()函数可以吗?

    这里自然也是分两种情况:

    1、 如果一个对象里面的成员属性是公有的,就可以使用这个函数在对象外面删除对象的公有属性。

    2、 如果对象的成员属性是私有的,我使用这个函数就没有权限去删除。

    虽然有以上两种情况,但我想说的是同样如果你在一个对象里面加上__unset()这个方法,就可以在对象的外部去删除对象的私有成员属性了。在对象里面加上了__unset()这个方法之后,

    在对象外部使用“unset()”函数删除对象内部的私有成员属性时,对象会自动调用__unset()函数来帮我们删除对象内部的私有成员属性。

    请看如下代码:

    <?php
    class Person
    {
      public $sex;
      private $name;
      private $age;
     
      public function __construct($name="", $age=25, $sex='男')
      {
        $this->name = $name;
        $this->age = $age;
        $this->sex = $sex;
      }
     
      /**
       * @param $content
       *
       * @return bool
       */
      public function __unset($content) {
        echo "当在类外部使用unset()函数来删除私有成员时自动调用的<br>";
        echo unset($this->$content);
      }
    }
     
    $person = new Person("小明", 25); // 初始赋值
    unset($person->sex);
    unset($person->name);
    unset($person->age);

    运行结果:

    当在类外部使用unset()函数来删除私有成员时自动调用的
    1当在类外部使用unset()函数来删除私有成员时自动调用的

  • 相关阅读:
    Dactor 一个好用的基于协程的全异步框架,适合复杂异步流程
    mysql原表增加字段且设置默认值及修改字段默认值
    js扩展
    mysql建表且设置主键自增
    mysql事务的实现方式——mvvc+锁
    mysql排他锁
    mysql的共享锁
    mysql的体系结构及sql的执行路径
    小程序 使用echarts 数据动态变换
    js 整理 前端知识点 前端面试题 (2020)(vue)
  • 原文地址:https://www.cnblogs.com/yang01/p/7290636.html
Copyright © 2011-2022 走看看