2017.8.07

一、常见的关键字和魔术方法

1、final关键字的应用

PHP 5 新增了一个 final 关键字。如果父类中的方法被声明为 final,则子类无法覆盖该方法。如果一个类被声明为 final,则不能被继承。

final关键字只能用来定义类和定义方法。

使用final关键字标记的类不能被继承final class Person{
   .......
}
class Student extends Person{
   .......
}

会出现错误提示。Fatal error :Class Student may not inherit from final class(Person)
使用final关键字标记的方法不能被子类覆盖class Person{
   final function Say(){
     ......
   }
}
class Student extends Person{
  function Say(){
    ......
  }
}

会出现下面错误:


Fatal Error:Cannot Override final method Person::say()



2、static关键字的使用

使用static关键字可以将类中的成员标识为静态的,既可 以用来标识成员属性,也可以用来标识成员方法。普通成员作为对象属性存在,以Person类为例,如果在Person中有一个"$conuntry = ‘china‘"的成员属性,任何一个Person类的对象都会拥有自己的一份$country属性,对象之间不会干扰。而static成员是作为整个类的属性存在,如果将$country属性使用static关键字标识,则不管通过Person类创建多少个对象(甚至可以是没有对象),这个static成员总是唯一存在的,在多个对象之间共享的。因为使用static标识 的成员属性是属于类的,所以与对象实例和其他的类无关。类的静态属性非常类似于函数的全局变量。类中的静态成员是不需要对象而使用类名来直接访问的,格式如下所示:

类名::静态成员属性名;

类名::静态成员方法名();

在类中声明的成员方法中,也可以使用关键字"self"来访问其他静态成员。因为静态成员是属于类的,而不属于任何对象,所以你不能用$this来引用它,而在PHP中给我们提供 的self关键字,就是在类的成员用来代表本类的关键字。格式如下 所示;

self::静态成员属性名; //在类的成员方法中使用这种方式访问本类中的静态成员属性

self::静态成员方法名();  //在类的成员方法中使用这种方式访问本类中的静态成员方法

  如果在类的外部访问类中的静态成员,可以使用对象引用和使用类名访问,但通常选择用类名来访问。

如果在类内部的成员方法中访问其他的静态成员,通常使用self的形式去访问,最好不要直接使用类名称。

在下面的例子中声明一个Myclass类,为了让类中的count属性可以在每个对象中共享,将其声明为static成员,用来统计通过Myclass类一共创建了多少对象。代码如下所示:

  <?php
         class Myclass{
              static $count;
              function __contruct(){
                   self::$count++;//在类的内部通常使用self形式访问
}

         static function getcount(){         

}

static function gecount()
      return self::$count;//在类的内部,通常使用self的形式去访问
}

}

Myclass::$count=0;
$myc1 = new Myclass();
$myc2 = new Myclass();

$myc3 = new Myclass();

echo Myclass::getCount();//在类的外部,通常选择用类名来访问。

echo $myc3->getCount();

上例的Myclass类中,在构造方法内部和成员方法getCount()的内部,都使用self访问本类中使用static标识为静态的属性count,并在类的外部使用类名访问类中的静态属性。可以看到同一个类中的静态成员在每个对象中共享,每创建一个对象静态属性count就自增1.用来统计实例化对象的次数。

另外在使用静态方法时需要注意,在静态方法中只能访问静态成员。因为非静态的成员必须通过对象的引用才能访问,通常是使用$this完成的。而静态的方法在对象不存在的情况下也可以直接使用类名来访问,没有对象就没$this引用,没有了$this引用就不能访问类中的非静态成员,但是可以使用类名或self在非静态方法中访问静态成员。

3、单态设计模式

3.1.单态设计模式含义:

单态模式的主要作用是保证在面向对象编程设计中,一个类只能有一个实例对象存在。作为对象的创建模式,单例模式确保某一个类只有一个实例,而且自行实例化并向整个系统全局地提供这个实例。它不会创建实例副本,而是会向单例类内部存储的实例返回一个引用。

3.2.单台模式的三个关键点:

① 需要一个保存类的唯一实例的静态成员变量;
②构造函数和克隆函数必须声明为私有的,防止外部程序new类从而失去单例模式的意义;
③必须提供一个访问这个实例的公共的静态方法(通常为getInstance方法),从而返回唯一实例的一个引用 。

<?php

class DB {
    private static $obj = null;           //声明一个私有的,静态的成员属性$obj
    private function__construct() {       //私有构造方法,只能在类的内部实例化对象
        //在该方法中完成数据局的连接等操作        echo "连接数据库成功<br>";
    }
    public static function getInstance() {  // 通过此静态方法才能获取本类的对象,该方法为静态方法,用类名调用
        if(is_null(self::$obj))  //如果本类中的$obj为空,说明还没有被实例化过
            self::$obj = new self();  //实例化本类对象
            return self::$obj;  //返回本类的对象
    }
    public function query($sql) {  //执行SQL语句完成对数据库的操作
        echo $sql;
    }
}
    $db = DB::getInstance();//类名调用   //只能使用静态方法getInstance()去获取DB类的对象,获取后执行下一句完成对数据库的操作
    $db -> query("select *from user");       //访问对象中的成员

4、instanceof关键字

PHP5的另一个新成员是instdnceof关键字。使用这个关键字可以确定一个对象是类的实例、类的子类,还是实现了某个特定接口,并进行相应的操作。在某些情况下,我们希望确定某个类是否特定的类型,或者是否实现了特定的接口。instanceof操作符非常适合完成这个任务。instanceof操作符检查三件事情:实例是否某个特定的类型,实例是否从某个特定的类型继承,实例或者他的任何祖先类是否实现了特定的接口。例如,假设希望了解名为manager的对象是否为类Employee的实例:

$manager = new Employee();
…
if ($manager instanceof Employee)
  echo "Yes";

有两点值得注意。首先,类名没有任何定界符(引号)。使用定界符将导致语法错误。其次,如果比较失败,脚本将退出执行。instanceof关键字在同时处理多个对象时特别有用。例如,你可能要重复地调用某个函数,但希望根据对象类型调整函数的行为。可以使用case语句和instanceof关键字来实现这个目标。

class test{}
class test{}
class testChilern Extends test{}
$a = new test();
$m = new test();
$i = ($m instanceof test);
if($i)
  echo ‘$m是类test的实例!<br />‘; // get this value
switch ($a instanceof test){
  case true :
    echo ‘YES<br />‘;
    break;
  case false :
    echo ‘No<br />‘; //get this value
    break;
}
$d=new testChilern();
if($d instanceof test)echo ‘$d是类test的子类!<br />‘; // get this value

5、克隆对象

<?php
    class Person {    //声明类Person,并在其中声明了三个成员属性,一个构造方法以及一个成员方法
        private $name;     //第一个私有成员属性$name用于存储人的名子
        private $sex;       //第二个私有成员属性$sex用于存储人的性别
        private $age;       //第三个私有成员属性$age用于存储人的age

        function __construct($name="", $sex="", $age=1) {  //构造方法在对象诞生时为成员属性赋初值
            $this->name=$name;
            $this->sex=$sex;
            $this->age=$age;
        }

        function __clone() {     //声明此方法则在对象克隆时自动调用,用来为新对象重新赋值
            $this->name="我是".$that->name."的副本";  //为副本对象中的name属性重新赋值
            $this->age=10;                          //为副本对象中的age属性重新赋值
        }        

        function say()  {       //一个成员方法用于打印出自己对象中全部的成员属性值
            echo "我的名子叫:".$this->name." 性别:".$this->sex." 我的年龄是:".$this->age."<br>";
        }
    }

    $p1=new Person("张三", "男", 20);   //创建一个对象并通过构造方法为对象中所有成员属性赋初值
    $p2=clone $p1;                   //使用clone克隆(复制)对象,并自动调用类中的__clone()方法
    $p1->say();                      //调用原对象中的说话方法,打印原对象中的全部属性值
    $p2->say();                      //调用副本对象中的说话方法,打印出克隆对象的全部属性值
?>

6、自动加载类

在面向对象程序设计时,通常为每个类单独建立一个PHP文件,使用时,可以用include包含一个类所在源文件,但是如果要使用太多的类,就比较麻烦。PHP提供了类的自动加载功能,__autoload全局函数,参数为类的名称。

此函数所调用的类源文件必须与autoload函数在同一个目录下:

<?php  
    function __autoload($className) {                            //在方件的上方声明一个自动加载类的方法
       // include("class_" . ucfirst($className) . ".php");         //在方法中使用include包含类所在的文件          include(strtolower($classname).".xxx.php")
    }

    $obj  = new User();      //User类不存在则自动调用__autoload()函数,将类名“User”做为参数传入
    $obj2 = new Shop();    //Shop类不存在则自动调用__autoload()函数,将类名“Shop”做为参数传入
?>      

7、对象的串行化

对象通过写出描述自己状态的数值来记录自己,称为对象的串行化。

在网络中传输对象的时候以及向数据库中保存文件的时候需要把对象串行化。

全部串行化:

1.serialize(对象名) 将指定的类对象串行化  $str=serialize($per)  //将per对象串行化,结果返回给$str

2.unserialize(串行化后的返回值) 返回结果是对象    $per=unserialize($str);

局部串行化:

3.__sleep() 串行化某对象的部分属性。

4.__wakeup()反串行化时,初始化(其实是修改)对象内容

前两个的使用方法我们大概已经介绍过,接下来我们简单介绍一下__sleep()和__wakeup()使用方法

1.如果我们只想串行化一个对象中的部分属性我们可以使用 __sleep()函数

在类定义中添加

function__sleep()//只序列化类中的name和age成员

{

$arr=new array(‘name‘,‘age‘); //name和age将被串行化,其他实属性将被忽略,反串行化后其他属性也将不存在 name和age必须是类中的属性 可以根据自己的实际需要增加

Return arr;

}

2.假如我们在类串行化的时候,per对象的name属性值为“姜彤”在反序列化的时候我想改成"张三"怎么办

function __wakeup()
{

This->name="张三";

}
时间: 2024-09-30 05:05:04

2017.8.07的相关文章

2017年07月03号课堂笔记

2017年07月03号 星期一  多云 空气质量:轻度污染~中度污染 内容:MySQL第四节课 in和not in:两个表的内连接:exists和not exsits的使用:all,any和some: 使用子查询的注意事项:sql优化(使用exists 代替 in):group by:两道mysql面试题 一.in和not in 1.in-- 使用in替换 等于(=)的子查询语句!-- in后面的子查询可以返回多条记录! 1)例题1 -- 查询年级编号是1或者2 的 所有学生列表 SELECT

2017年07月05号课堂笔记

2017年07月05号 星期三 多云 空气质量:中度污染 内容:mysql第五节课+MySQL自测考试 表连接查询:内连接,左右外连接,自连接 事务:事务的特性 ACID,demo(模拟 银行转账)开启,回滚,提交,关闭/开启事务自动提交 一.表连接查询 1.概念: 1)内连接 : 通过匹配两个表中公共列,找到 公共的行! 2)左外连接: 以左表为准,右表中没有数据返回null 3)右外连接: 以右表为准,左表中没有数据返回null 4)自连接:  把一个表当成多个表来使用 关键是 使用别名 2

异常处理——2017.08.07

一 异常 异常是什么?异常是程序员修正之后还能继续运行的错误. 分类:Checked异常和Runtime异常,Checked异常是指在编译阶段被处理的异常,Runtime异常是指在运行期间才能发现的异常. 二 异常处理机制 1 使用try...catch捕获异常 try { //业务实现代码 ... } catch(Exception e) { //错误处理代码 } 按照这种逻辑关系进行处理,但是如果执行try块里的业务逻辑代码时出现异常时,系统会自动生成一个异常对象,该异常对象被提交给Java

2017/04/07

今天s跟我说觉得我是一个需要拿鞭子抽的人,要抽着走.我说你是说我惰性太大么,他说是,我说我是一个很push的人,努力去改变自己.我说你是不是没表达好,他说好像是.回头想想,他说的惰性,应该是怂,不敢于去做自己.总要有人再后边不停催促,赶着,或者说用鞭子抽才会去做.想想是这样,很多事情想做顾虑太多,顾虑着顾虑着也就不去做了. 今天,把<未来简史>读完了,对于未来似乎存在了比过往历史更多的不确定性,人工智能的发展会不会改变整个人类现有的格局,甚至统治人类,都未可知.但可以确定的是,科技将在未来展现

2017.05.07作业

一.接口测试基础: 1.测试http接口: 1.1.接口调用方式分为两种:key-value和json串:keyvalue就类似于URL后边添加字段和值这种,而json串方式是在body里输入具体的传参内容 例子:key-value形式:url?param=value&param2=value 1.2.json串不能通过拼接参数完成,需要借助工具来完成 例如postman 2.HTTP状态码: 200 2开头的都表示这个请求发送成功,最常见的就是200,就代表这个请求是ok的,服务器也返回了.

2017.11.07

一天讲完了HTML5,又一天讲完了CSS,感觉大脑已经不够用了,知识点多而杂,主要感觉时间太快,没太有时间去消化,只能晚上加加班啦.通过这2天的学习让我了解到了HTML的标签,表格表单,框架等等.今天讲了CSS样式表的基本概念和样式属性,总结还是要多练多敲代码.下面是我记得一些知识点. CSS样式:(1)內联式(直接在标签里面写样式) 例如:<div style="width:100px;height;100px;></div>(2)内嵌式(直接嵌入到head标签里面,以

switch选择结构 2017.11.07

switch (表达式){ case 常量1: //代码块1 ; break; case 常量2 : //代码块2  ; break; default:  //其他 的意思,如果没有选择常量,则默认选择default //代码块n; break; } 如图 //也可多重选择只是常量必须相等 例如: int num=3; switch(num){ case1: case5: case3: System.out.println("奇数"); break; case2; case4; cas

【2017.11.07】noip赛前集训 | T1 遭遇【DP】

T1 遭遇 [题意] ??座楼房,立于城中. 第??座楼,高度???. 你需要一开始选择一座楼,开始跳楼.在第??座楼准备跳楼需要????的花费. 每次可以跳到任何一个还没有跳过的楼上去.但跳楼是有代价的,每次跳到另 外一座楼的代价是两座楼高度的差的绝对值,最后一次从楼上跳到地面上不需 要代价(只能跳到地上一次).为在代价不超过??的情况下,最多跳几次楼. (一座楼只能跳一次,且每次跳楼都要计算准备的花费) [题解] 跳楼时,楼房的高度是具有单调性的,所以先按照高度排序. f[i][j]表示已经

2017.12.07 Ajax获取服务器数据并发送到前端

1.前端:在React渲染页面之前就加载服务器数据: componentWillMount() { console.log("aaaaaaaa"); var data2={ action:"queryTaskOfManager" }; Common.getData(JSON.stringify(data2),function (ret) { alert(ret); }); } 2.前端调用这个React生命周期函数: 3.ajax文件封装成组件后,导出: 4.Aja