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()函数来删除私有成员时自动调用的

原文地址:https://www.cnblogs.com/yang01/p/7290636.html