美文网首页我爱编程
PHP 学习笔记(三)

PHP 学习笔记(三)

作者: _1633_ | 来源:发表于2018-04-10 12:24 被阅读0次

    参考资料:PHP5 权威编程


    笔记开始

    PHP 中的类和对象

                对象:万物皆对象;

                类: 任何对象,都可以人为规定为某种类型(类别)。

    PHP中的对象

                类是描述一类事物的一个总称,是具有相同特征的该类事物的一个通用名称。

                对象是一个明确的具体的物体,是某个类中的一个实物(类就是一个抽象的概念)。对象一定隶属于某个类--------有类才有对象,先有类再有对象

                属性和方法

                在面相对象过程中

                属性就是原来的变量,写在一个类中,原来的变量就称为属性(类的变量成员叫属性);

                方法就是原来的函数,写在一个类中,原来的函数就称为方法。

    属性和方法

                对象的创建

    4种创建方法

                对象的传值方式

                  对象的存储模式(结构):

                            $变量 ---->  对象标识符/编号(#1) ----->  #1对象数据本身

                            并且:该变量中存储的实际是该对象的标识符/编号。这个标识符或编号有能力去“指向对象”;

    值传递 引用传递

                        对象中的 值传递引用传递 结果一样, 但是过程却不相同

                        值传递过程

    值传递

                        引用传递

    引用传递 引用传递

            类中成员

                    类中成员分为3大类

                        属性:1 普通属性  2 静态属性

                        方法: 1 普通方法 2 静态方法 3 构造方法 4 析构方法

                        常量

                    类常量

                        定义形式 

                            class 类名{

                                const 常量名 ;     // 不能使用define

                            }

                        使用形式

                            常量的使用,是通过类名,并使用范围解析符(::)来取用的;

                            类名::常量名;

    常量使用形式

                    普通属性(实例属性)

                        定义形式

                            class 类名{

                                var $属性名 = 初始值;

                                var $属性名;

                                // 另一种形式

                                public $属性名 = 初始值;

                                public $属性名;

                            }

                        使用形式

                            $对象->属性名;(没有$符号!!)


                    静态属性

                        静态属性,本质上也是“变量”,但其有一个特点就是:该变量只隶属于“类”,即:

                        一个类中的一个静态属性,就只有“一份数据”;

                        一个类中的一个实例属性,就可以有“多份数据”——每创建一个对象出来,就会有一份数据;

                        定义形式

                            class  类名{

                                static $属性名 =  初始值;

                                static $属性名;

                            }

                        使用形式

                            使用类名和范围解析符(::)来对静态属性进行操作:

                            类名::$静态属性名;    //注意:属性名带$符号!!!!!!

    静态属性只有一份数据

                    1,实例属性,是每个对象都可以不一样的数据,也是每个对象都“独自拥有”的数据;

                    2,静态属性,他不属于任何一个对象,而只属于该类本身,也可以理解为为所有对象所共有的数据;

                    普通方法(实例方法)

                         定义形式

                            class  类名{

                                function 方法名($形参1,$x形参2....){

                                    // code.......

                                }

                            }

                        调用形式

                        $对象名->方法名(实参1,实参2,....);

                    静态方法

                           一个类中定义的方法,只隶属于这个类本身,而不是隶属于这个类的对象。

                           定义形式

                                class  类名{

                                     static function 方法名($形参1,$x形参2....){

                                        // code.......

                                        }

                                }

                            调用形式

                            类名::方法名(实参1,实参2,....);

    静态方法

                    self关键字:用在方法中,表示该方法所在的类

                    static关键字代替self关键字的位置,除了具有self作用外,还具有更灵活的作用,那就是所谓“后期静态绑定”。

                    构造方法(__construct)

                    构造方法是一个类在进行实例化(new一个对象出来)的时候,会 首先自动调用 的方法。主要的目的是为了在new一个对象的时候,给该对象设置一些“初始值”(初始化工作);构造方法的参数没有规定,通常是根据实际的需要来定义,目的是为了对象属性数据的初始化。

      构造方法(__construct)  


                    析构方法(__destruct)

                    析构方法是一个对象被销毁的时候被 自动调用 的方法,自己无法调用。

                    析构方法  不能带参数(形参),只能是public的。但方法中也可以使用$this这个词,代表“当前对象”。

                    如果一个类中定义了析构方法,则销毁对象时就会调用该方法。

                    如果一个类中没有定义析构方法,则销毁对象时就会调用其父类的析构方法(如果有)

     析构方法(__destruct)

                       

           对象在哪些情况下会被销毁?

                    1,如果程序结束,所有变量都会被销毁,自然,变量所代表的对象也会被销毁;

    程序结束 对象销毁

                    对象销毁的顺序,默认情况下,跟其创建的顺序相反

                    2,当一个对象没有任何变量“指向”它的时候,即使程序还没有结束,也会被销毁;

    一个对象没有任何变量“指向”它

                        此时,$obj1 断开了指向 ,但是程序还没也结束,此时,也会销毁对象。此时执行析构方法。

                    3,当变量赋值为标量,不能再指向对象,对象就会被销毁。

    变量赋值为标量

              类的继承

                        将一个类A中的特性信息,传递到另一个类B中,此时就称为:

                        B继承A

                        A派生出B;

                        基本语法:extends

    extends

                        说明

                            父类/子类:已有类为父类,新建类为子类。父类又可以称为“基类”,上级类,子类又称为派生类,下级类,

                            单继承:一个类只能从一个上级类继承其特性信息。PHP和大多数面向对象的语言都是单继承模式。C++是多继承。

                            扩展:在子类中再来定义自己的一些新的特有的特性信息(属性,方法和常量)。没有扩展,继承也就没有意义了。

              访问控制修饰符    

                            public:公告的,在所有位置都可以访问;

                            protected:受保护的,只能在该类内部和该类的子类或者父类中访问和使用;

                            private:私有的,只能在该类内部访问。

                            形式    

                                class 类名{

                                    访问控制修饰符  属性或者方法

                                }

                            作用:用来 限制 其说修饰的成员的 可访问性,即用

                            对象->实例属性和方法  或者 类::静态属性和静态方法   的合理性。

                        访问控制修饰符,需要结合使用该语法形式的所在位置,才能确定是否可访问。

                       3个访问位置:类的内部,  继承类的内部,类的外部  

    访问的权限

                        总结:

                        1,public修饰的成员,哪里都能访问

                        2,类的内部,可以访问任何级别的成员

                        3,public具有最宽泛的可访问性;private具有最狭小的可访问性;protecte则居中;

    访问控制修饰符    外部 访问控制修饰符    内部 访问控制修饰符    继承类内部  

              parent关键词

                        paren在面向对象语法中,代表“父类”。本质上就是代表父类这个“类”,而不是父类的“对象”;

                        使用方式为:

                          parent::属性或方法; //通常是静态属性或静态方法,但有时候可能是实例属性或实例方法;

      parent关键词

                        三个关键字对比

    三个关键字对比

                       构造方法  析构方法 在父类和子类中的运用

                        1,如果一个类 有构造方法,则实例化这个类的时候,就不会调用父类的构造方法(如果有);

                        2,如果一个类没有构造方法,则实例化这个类的时候,就会自动调用父类的构造方法(如果有);                

                        3,如果一个类 有析构方法,则销毁这个类的时候,就不会调用父类的析构方法(如果有);

                        4,如果一个类没有析构方法,则销毁这个类的时候,就会自动调用父类的析构方法(如果有);

                        5,如果一个类中有构造方法或析构方法,则就可以去“手动”调用父类的同类方法(如果有);

                    手动调用的语法形式总是这样:

                    parent::构造方法或析构方法()

      parent::构造方法或析构方法()


           覆盖(override)

                    覆盖,又叫“重写”,将一个类从父类中继承过来的属性和方法“重新定义”——此时相当于子类不用父类的该属性或方法,而是重新定义。

    覆盖

                访问控制权限:

                        子类覆盖的属性或方法的访问控制权限,不能“低于”父类的被覆盖的属性或方法的访问控制权限:

                    具体来说:

                    父类:public 子类:只能是public

                    父类:protected 子类:可以是protected和public

                    父类:private 子类:不能覆盖!——既父类的私有成员,不存在被子类覆盖的可能。

                    方法的参数形式:

                    子类覆盖父类的同名方法的时候,参数要求跟父类保持一致;

                    特例:

                    构造方法重写的时候参数可以不一致

                    小注意:

                    虽然父类的私有属性不能被覆盖,但子类却可以定义自己的跟父类同名的属性;

                    虽然父类的私有方法不能被覆盖,但子类也不能定义自己的同名方法;


            最终类

                最终类,其实就是一种特殊要求的类:要求该类不允许往下继承下去。

                形式:

                    final  class类名{

                    //类的成员定义。。。跟一般类的定义一样!

                    }

            最终方法

                最终方法,就是一个不允许下级类去覆盖的方法!!

                形式:

                    class类名{

                        final  function方法名(形参列表...){ 。。。。。 }

                    }

           设计模式

                设计模式就是解决某个问题的一般性代码的经验性总结。

                            工厂模式

                                所谓工厂模式,就是这样一个类(就是所谓的工厂类):它可以根据“传递”给他的类名,而去生产出对应的类的对象。

                               工厂模式是我们最常用的实例化对象模式了,是用工厂方法代替new操作的一种模式

    工厂模式

                            

                            单例模式

                            通过单例模式可以保证系统中,应用该模式的类一个类只有一个实例。即一个类只有一个对象实例。

    单例模式

          抽象类和抽象方法

                    抽象类:一个不能实例化的类

                        形式:abstract   class  类名{    }        

                    抽象方法:是一个只有方法头,没有方法体的方法定义形式

                        形式:abstract function 方法名();    //注意,这里必须有分号;

                    抽象类  和  抽象方法  注意事项

                    1 一个抽象方法必须在抽象类中,抽象类中不一定有抽象方法(不常见);

                    2 被定义为抽象的方法只是声明了其调用方式(参数),不能定义其具体的功能实现。 抽象方法是为了规定下级类中必须去完成对抽象方法的详细描述;

                    3子类实现父类的抽象方法的时候,其形参也应该跟父类保持一致,其访问权限也不能更小;——其原因其实这是“重写现象”,自然应该遵循重写的要求;

    抽象类和抽象方法

            重载技术 

                    重载的基本概念

                            PHP所提供的重载(overloading)是指动态地创建类属性和方法。简单来说,当对一个对象或类使用其未定义的属性或方法的时候,其中的一些“处理机制”。

                            我们是通过魔术方法(magic methods)来实现的。 

    重载

                    属性重载

                        就是对一个对象的不存在的属性进行使用的时候,这个类中预先设定好的应对办法(处理机制);

                        属性,本质,就是变量,其只有4个操作:

                        取值:当对一个对象的不存在的属性进行“取值”的时候,就会自动调用内部方法:__GET()

                        __GET($属性名)

                        该方法可以带一个形参,表示这个要对之取值的不存在的属性名(字符串);

     __GET

                         赋值:当对一个对象的不存在的属性进行“赋值”的时候,就会自动调用内部方法:__SET()

                        __SET($属性名,值)

                         它有2个形参,分别代表要对不存在的属性进行赋值的时候的“属性名”和“属性值”;

    __SET($属性名,值)

                        判断(isset):当对一个对象的不存在的属性进行isset()判断的时候,就会自动调用内部方法:__isset()

                        __isset(属性名)

                 __isset(属性名) 

                        销毁(unset):当对一个对象的不存在的属性进行unset()销毁的时候,就会自动调用内部方法:__unset()

                    __unset(属性名)

      __unset(属性名)

                    方法重载

                    当对一个对象的不存在的实例方法进行“调用”的时候,会自动调用类中的__call()这个魔术方法;

                    当对一个类的不存在的静态方法进行“调用”的时候,会自动调用类中的__callstatic()这个静态魔术方法

                    __call($method_name , $argument )

                    $method_name 表示要调用的不存在的方法名

                    $argument  表示要调用的不存在的方法所使用的实参数据,是一个数组

       __call($method_name , $argument )  

            接口

                    使用接口(interface),可以指定某个类必须实现哪些方法,但不需要定义这些方法的具体内容

                    接口是通过interface关键字来定义的,就像定义一个标准的类一样,但其中定义所有的方法都是空的

                    接口中定义的所有方法都必须是公有,这是接口的特性。

                    接口里面只能放 “抽象方法” 和 “常量”。

                    形式:

                        interface 接口名{

                            常量1;

                            常量2;    

                            .........

                            抽象方法1;

                            抽象方法2;

                        }

                            接口常量的使用形式为:接口名称::常量名称;

                            接口中的抽象方法,不要使用abstract修饰,也不需要使用访问控制修饰符,因为其天然就是public。

    接口

                            接口的作用

                            PHP是单继承,但是运用中往往要运用到 多继承,接口就是对没有多继承的类之间关系的一个补充。

                            接口可以实现“多继承”——但此时不称为继承而已,而是称为“实现”;

                                即: 接口1  -->>类1;   称为:类1实现了接口1;

                                其本质,其实就是类1中,有了接口1中“特征信息”

                            使用形式:

                            class 类名 implements接口1,接口2.....{

                            }

    接口作用

           

           类的自动加载

                        当某行代码需要一个类的时候,php的内部机制可以做到“自动加载该类文件”,以满足该行需要一个类的这种需求。  

                        什么时候需要一个类

                        1 new一个对象的时候;

                        2 使用一个类的静态方法的时候;

                        3 定义一个类(B)并以另外一个类(A)作为父类的时候。

    自动加载函数    

                使用条件

                    1, 当需要一个类的时候,就会自动调用某个函数(默认是__autoload),并传入所需要的类的名字;

                    2,一个类应该保存到一个独立的“类文件中”:即其中只有该类的定义,没有别的代码

                    3,习惯上,类文件的命名要有一定的“规则”,通常是:类名.class.php;

                    4,在自动加载函数中,形参为需要加载的类名,所以要拼凑好正确的路径。

            自定义自动加载函数

                __autoload 函数是系统定义的自动加载函数,在需要时,我们可以自定义 自动加载函数。

               形式

               spl_autoload_register(“函数1”); //声明“函数1”作为自动加载函数;

               spl_autoload_register(“函数2”); //声明“函数2”也作为自动加载函数;

                .........

                定义(与__autoload一样)

                function 函数1( $class_name ){

                  //.......

                }

                function函数2( $class_name ){

                    //.......

                }

    自定义自动加载函数


            对象的复制(克隆)

                对象的克隆,就是用于将一个对象“制作”双份,类似之前普通数据的“值传递”;   

                  定义

                    $obj2  =  clone  $obj1; //这样,就有一个跟$obj1完全一样的新的对象。

       对象的复制(克隆)

                __clone 魔术方法

                使用 clone  会克隆出一个跟当前对象一样的新的对象,并且会调用该类中的魔术方法:__clone ,只要 该类中有该方法。    

                在单例模式中,应该禁止对该单例的克隆,所有要在该类中禁止__clone 魔术方法,做法就是私有化__clone

                第4步私有化这个克隆的魔术方法

                private function __clone {//不用写代码}


            对象的遍历     

            对象的遍历,跟数组的遍历,一样!只能遍历出对象的“实例属性数据”。

            foreach($对象名  as  $key=>$value){

                    //处理$key  $value

             }

            说明:1 $key 是对象的属性名,$value 是其对应的值;

                       2 能变量出来的属性,根据访问控制权限,只能是在该范围中的“可访问属性”;

    对象的遍历

            PHP内置标准类  

                   PHP中有很多 定义好的类,其中有一个叫  内置标准类。该类的内部什么都没有定义,可以理解为:

            class stdclass{    }

    stdclass

            作用:1 可以临时存储数据:$obj2 -> p1 = 100;

                       2 当其他数据类型转换为对象类型的时候,得到就就是一个内置标准类(stdclass)的一个对象实例;

                        形式: $obj = (object)其他数据类型;

                        ①数组转为对象:数组的键名作为属性名,键值作为对应的值;数字下标的数组,不推荐转换,因为无法通过对象语法获取。

    数组转对象 得到的是内置标准类的一个实例

                            ②null 转为对象 为空对象

    内置标准类

                            ③其他 标量数据 (布尔(boolean),整型(interger),浮点型(float/double),   字符串(string)转为对象,键名为 固定的“scalar”,值为 该变量的值;

    其他 标量数据 转为对象

            类型约束

                就是要求某个变量只能使用(接收,存储)某种指定的数据类型;

                PHP只支持在函数(或方法)的形参上,设定类型的约束目标,形式:

                function 函数名 (【要求使用的类型】形参1,【要求使用的类型】形参2.......){   }

                说明:1 定义一个函数的时候,可以设定约束类型也可以不设定;

                           2 如果设定了约束类型,该实参就必须是该类型,否则就会报错;

                           3 能够使用约束类型的就只有一下几种:数组(array),对象(使用类的名称,表示该实参必须是该类的一个实例),接口(使用接口的名称,表示该实参必须是该接口的类的一个实例)

        类型约束

            类相关的魔术方法

                    序列化与反序列化技术

                    序列化:就是将一个变量所代表的“内存”数据,转换为“字符串”形式并持久保存在硬盘上的一种做法。

                    $v1  = 100;

                    $s1 = serialize($v1); //将任何类型的变量数据,转化为字符串

                    file_put_contents('要保存的目标文件名',$s1);//保存到文件中去

                    反序列化:就是将序列化之后保存在硬盘上的“字符串数据”,恢复为其原来的内存形式的变量数据的一种做法。

                    $s1 = file_get_contents( ‘保存序列化数据的目标文本文件’); //从一个文件里读出其中的所有字符

                    $v1 =  unserialize( $s1 ); //将该字符串数据,反序列化转换为变量(数据)

    序列化与反序列化

                    对象的序列化和反序列化

                    对象序列化只能保存其属性,而方法被忽略;而且会自动调用该对象所属类的魔术方法:__sleep()(前提是有该方法),且该方法必须返回一个数组,数组中是“计划”要进行序列化的属性名;

    对象的序列化

                    对象反序列化其实是恢复其原来保存起来的属性数据,而且,此时必然需要依赖该对象原本的所属类;对象在反序列化的时候,会自动调用该对象所属类的这个魔术方法:__wakeup()(前提是有该方法)。


                 __tostring()魔术方法(常用)

                  将一个对象“当做”一个字符串来使用的时候,会自动调用该方法,并且在该方法中,可以返回一定的字符串,以表明该对象转换为字符串之后的结果。

                    注意:如果没有定义该方法,则对象无法当做字符串来使用。

    __tostring 

             与类相关的方法属性

                    魔术常量:以前的笔记中有的 __FILE__   __DIR__  __LINE__

                    __CLASS__: 代表当前其所在的类的类名;

                    __METHOD__:代表其当前所在的方法名;

    魔术常量

            与类有关的系统函数:

            class_exists(“类名”), 判断一个类是否存在(是否定义过)

            interface_exists(“接口名”), 判断一个接口是否存在(是否定义过)

            get_class( $obj ), 获得某个对象$obj的所属类

            get_parent_class($obj ), 获得某个对象$obj的所属类的父类

            get_class_methods(), 获得一个类的所有方法名,结果是一个数组,里面存储的是这些方法的名称

            get_class_vars(), 获得一个类的所有属性名。结果是一个数组,里面存储的是这些属性的名称get_declared_classes() 获得“整个系统”所定义的所有类名;

            与对象有关的系统函数:

            is_object( $obj ): 判断某个变量是否是一个对象;

            get_object_vars( $obj ):获得一个对象的所有属性;结果是一个数组,里面存储的是这些属性的名称

            与类有关的运算符:

            instanceof:  判断一个“变量”(对象,数据),是否是某个类的“实例”;

       instanceof

            static关键字的新用法和总结(重要)

                static这个关键字,也可以像“self”一样,代表“当前类”,用于访问一个类的“静态属性或静态方法”;但,static,在应用中,更灵活,因此更常见。因为static,它代表的是“调用”当前方法的类,而不是“其代码所在的类”;self它就比较死板,只代表这个单词本身所在位置的所在类。

     static和self

    相关文章

      网友评论

        本文标题:PHP 学习笔记(三)

        本文链接:https://www.haomeiwen.com/subject/xcnqcftx.html