【代码总结】PHP面向对象之常见的关键字和魔术方法

一、关键字的使用

1、final关键字

  只能用来修饰类 和 成员方法  不能修饰成员属性
  被final修饰的类不能被继承
  用final修饰的成员方法 不能被子类覆盖(重写)

<?php 
    // final class A{ //被修饰的类不能被继承
    class A{
    //被修饰成员方法不能被子类覆盖
    final public function func(){
        echo "你好";
        }
    }
    class B extends A{
        public function func(){
            echo "今天周六...";
        }
    }
    $a = new B();
    $a->func();
    
    //显示 Fatal error: Cannot override final method A::func() in E:\Local test\phpstudy\2.php on line 13
 ?>

 

2、static关键字的使用

  主要用于修饰类与成员方法(函数)可以不用new(实例化)就可以直接使用方法:如 类名::方法名

  在静态的成员方法中不能使用$this关键字,只能访问静态成员
      注意:静态方法在实例化后的对象也可以访问    //$对象名->静态方法名

       访问形式
            在类的内部  self::$属性名  self::方法名
            在类的外部  类名::$属性名  类名::方法名

<?php 
    class demo{
        //成员属性
        static public $name = "SQYY";
        //成员方法
        static public function func(){
            echo "我是一个方法...";
        }
        public function func2(){
            echo self::$name;
            self::func();
        }
        public function func3(){
            echo "在php5.3之前我是静态的...";
            //提示 : Strict Standards: Non-static method demo::func3() should not be called statically in E:\Local test\phpstudy\2.php on line 23
        }
    }
    echo demo::$name;
    demo::func();
?>

 

3、单例设计模式
        在当前脚本中只产生一个该类对象
        1.阻止在类外部使用new来实例化对象
                将构造方法私有化
        2.在类内部声明一个方法来创建对象
                将成员方法声明静态的
        3.把创建的对象存入一个位置
                把创建的对象存到静态属性中 作为依据

3、const关键字

  define("变量名","值")

  const修饰的成员属性为常量,只能修饰成员属性

  类中

  1.常量建议使用大写,不能使用$

  2.常量一定要在声明时给好初值

  3.常量的访问方式和static的访问方式相同,但只能读


            类的内部 self::常量名 注意 没有$
            类的外部 类名::常量名  没有$

<?php 
    class MyClass{
        const CONSTANT = 'CONSTANT value';  //使用const声明一个常量,并直接赋上初始值
        function showConstant(){    //声明一个成员方法并在其内部访问本类的常量
            echo self::CONSTANT.'<br>';        //使用self访问常量,注意常量前不要加 $
        }
    }
    echo MyClass::CONSTANT . '<br>';   //在类外部使用类名称访问常量,也不要加 $
    $class = new MyClass;       
    $MyClass -> showConstant()   //调用对象中的方法
 ?>

 

4、instanceof关键字

   instanceof”操作符用于检测当前对象实例是否属于某一个类的类型。
        检测当前对象是否为该类或者该类的后辈类的实例化

<?php 
         class Person{}
        class Student extends Person{}

        $p = new Person();
        $s = new Student();

        $a = $p instanceof Student;    //结果为false
        $b = $s instanceof Student ;   //结果为true
        $c = $s instanceof Person;    //结果为true

二、重载

  属性重载中的四个魔术方法:__set() __get() __isset() __unset()

      * __get():当我们直接输出一个对象中的非公有属性时会自动调用的方法,
                并将属性名以第一个参数传进去。
                __get($name){...}
                
      * __set(); 当我们直接设置一个对象中的非公有属性时会自动调用的方法,
                并将属性名以第一个参数,值作为第二参数传进去。
                __set($name,$value){...}

       __isset()当对未定义的变量调用isset() 或 empty()时,__isset() 会被调用。
           //当isset判断一个对象的非公有属性是否存在时,自动调用此方法。
           public function __isset($param){
              return isset($this->$param);
           }
           
       __unset()当对未定义的变量调用unset()时,__unset() 会被调用。
           //当unset销毁一个对象的非公有属性时,自动调用此方法。
           public function __unset($param){
              unset($this->$param);
           }

 

三、其他的魔术方法

1、克隆对象

  对象复制clone 克隆一个对象,因为对象属于引用类型,普通的“=”号属于引用赋值

$p1 = new Person();
$p2 = clone $p1; 
$p1 -> say();
$p2 -> say();

2、类中通用的方法 __toString()

  当我们直接要输出一个对象时,如echo $a,print $a,那么会自动调用的方法。
        注意:__toString()方法必须返回一个字串类型的值。

<?php 
    class Demo{
        public $name = "SQYY";

        public function func(){
            echo $this->name;
        }
        //该魔术方法中必须返回一个字符串
        public function __toString(){
            return "Hello";
        }
    }
    // 实例化对象
    $aa = new Demo();
    echo $aa;   //直接输出对象引用 则自动调用了对象中的__toString()方法输出Hello
 ?>

 

3、__call()方法的应用

  调用对象中不存在的方法时会自动调用该方法。

  __call($function_name, $args)
  $function_name  访问不存在的成员方法名称的字符
  $args  访问不存在的成员方法中传递的参数数组
<?php 
    class TestClass{
        function printHello(){
            echo 'Hello<br>';
        }
        function __call($functionName,$args){
            echo '你所调用的函数:'.$functionName. '(参数:';   //输出调用不存在的方法名
            print_r($args);    //输出调用不存在的方法时的参数列表
            echo ')不存在!';
        }
    }
    $obj = new TestClass();
    $obj -> printHello();    //输出 Hello
    $obj -> myFun('one',2,'three');  // 输出 你所调用的函数:myFun(参数:Array ( [0] => one [1] => 2 [2] => three ) )不存在!
?>

4、自动加载类

__autoload ( string $class )

$class 需要加载的类名称字符串

 没有类是自动调用 __autpload函数
<?php 
    //声明一个自动加载类的魔术方法 __autoload()
    function __autoload($className){
        //在方法中使用indlude包含类所在的文件
        include(strtolower($className)  .'.class.php');
        }
    $obj = new User();   //User类不存在则自动调用__autoload()函数,将类名'User'作为参数传入
?>

5、对象串行化

(1)、串行化

使用serialize()函数来穿行化一个对象,把对象转换为二进制字符串。serialize()函数的参数即为对象的引用名,返回值为一个对象被串行化后的字符串。serialize()返回的字符串含义模糊,一般不会解析这个字符串来得到对象的信息 
创建一个脚本文件person.class.php,并在文件中声明一个person类,类中包含三个成员属性和一个成员方法
脚本代码person.class.php如下所示
<?php
class  Person{
    private $name;
    private $sex;
    private $age;
    
    function __construct($name='',$sex='',$age=''){
        $this->name = $name;
        $this->sex = $sex;
        $this->age = $age;
    }
    public function say(){
        echo "我说话呢...";
    }
}
?>
创建一个Person类,在文件包含person.class.php文件,将person类加载进来,然后使用serialize()函数先将对象串行化,再将串行化后得到的字符串保存到file.txt文件中。
脚本文件serialize.php中代码如下
<?php 
    require 'person.class.php';
    $person = new person('张三','男','20'); 
    $person_string = serialize($person);  //通过serialize()函数将对象串行化,返回一个字符串
    file_put_contents('file.txt',$person_string);    //将对象串行化后返回的字符串保存到file.txt中
 ?>

通过上面的示例,通过file_put_content()函数成功的将person类实例化的对象保存到file.txt文件中

 O:6:"Person":3:{s:12:" Person name";s:6:"张三";s:11:" Person sex";s:3:"男";s:11:" Person age";s:2:"20";} 
(2)反串行化
  把对象串行化后转换的二进制字符串再转换为对象,我们使用unserialize()函数来反串行化一个对象。这个函数的参数即为serialize()函数的返回值

我们并不需要解析在file.txt中保存的这个串来得到对象的信息,它只是通过对象serialize()函数串行化后返回描述对象信息的字符串,
目的是将对象持久的好存起来,以后在需要这个对象,只要通过unserialize()函数将file文件保存的字符串再反串行化成对象即可
<?php
    require 'person.class.php';
    $person_string = file_get_contents('file.txt');
    $person = unserialize($person_string);
    $person -> say();
 ?>

6、__sleep和__wakeup()

<?php
class  Person{
    private $name;
    private $sex;
    private $age;
    
    function __construct($name='',$sex='',$age=''){
        $this->name = $name;
        $this->sex = $sex;
        $this->age = $age;
    }
    public function say(){
        echo "我说话呢...";
    }
}
function __sleep(){
    $arr = array('name','age');   //数组中的成员$name和$age将被串行化,成员$sex则被忽略
    return($arr);     //返回一个数组
}
function __wakeup{
    $this -> age = 40;   //重新组织对象时,为新对象中的$age属性重新赋值
}
?>

 



posted @ 2017-05-09 03:12  水清云影  阅读(527)  评论(0编辑  收藏  举报