PHP实用教程第三版笔记,PHP 学习笔记(三)

参考资料:PHP5 权威编程

81d3ffdaf0a5

笔记开始

PHP 中的类和对象

对象:万物皆对象;

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

81d3ffdaf0a5

PHP中的对象

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

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

属性和方法

在面相对象过程中

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

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

81d3ffdaf0a5

属性和方法

对象的创建

81d3ffdaf0a5

4种创建方法

对象的传值方式

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

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

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

81d3ffdaf0a5

值传递

81d3ffdaf0a5

引用传递

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

值传递过程

81d3ffdaf0a5

值传递

引用传递

81d3ffdaf0a5

引用传递

81d3ffdaf0a5

引用传递

类中成员

类中成员分为3大类

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

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

常量

类常量

定义形式

class 类名{

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

}

使用形式

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

类名::常量名;

81d3ffdaf0a5

常量使用形式

普通属性(实例属性)

定义形式

class 类名{

var $属性名 = 初始值;

var $属性名;

// 另一种形式

public $属性名 = 初始值;

public $属性名;

}

使用形式

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

静态属性

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

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

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

定义形式

class  类名{

static $属性名 =  初始值;

static $属性名;

}

使用形式

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

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

81d3ffdaf0a5

静态属性只有一份数据

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

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

普通方法(实例方法)

定义形式

class  类名{

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

// code.......

}

}

调用形式

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

静态方法

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

定义形式

class  类名{

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

// code.......

}

}

调用形式

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

81d3ffdaf0a5

静态方法

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

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

构造方法(__construct)

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

81d3ffdaf0a5

构造方法(__construct)

析构方法(__destruct)

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

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

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

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

81d3ffdaf0a5

析构方法(__destruct)

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

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

81d3ffdaf0a5

程序结束 对象销毁

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

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

81d3ffdaf0a5

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

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

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

81d3ffdaf0a5

变量赋值为标量

类的继承

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

B继承A

A派生出B;

基本语法:extends

81d3ffdaf0a5

extends

说明

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

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

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

访问控制修饰符

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

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

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

形式

class 类名{

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

}

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

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

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

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

81d3ffdaf0a5

访问的权限

总结:

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

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

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

81d3ffdaf0a5

访问控制修饰符    外部

81d3ffdaf0a5

访问控制修饰符    内部

81d3ffdaf0a5

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

parent关键词

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

使用方式为:

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

81d3ffdaf0a5

parent关键词

三个关键字对比

81d3ffdaf0a5

三个关键字对比

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

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

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

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

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

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

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

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

81d3ffdaf0a5

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

覆盖(override)

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

81d3ffdaf0a5

覆盖

访问控制权限:

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

具体来说:

父类:public子类:只能是public

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

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

方法的参数形式:

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

特例:

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

小注意:

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

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

最终类

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

形式:

finalclass类名{

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

}

最终方法

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

形式:

class类名{

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

}

设计模式

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

工厂模式

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

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

81d3ffdaf0a5

工厂模式

单例模式

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

81d3ffdaf0a5

单例模式

抽象类和抽象方法

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

形式:abstract   class  类名{    }

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

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

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

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

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

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

81d3ffdaf0a5

抽象类和抽象方法

重载技术

重载的基本概念

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

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

81d3ffdaf0a5

重载

属性重载

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

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

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

__GET($属性名)

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

81d3ffdaf0a5

__GET

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

__SET($属性名,值)

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

81d3ffdaf0a5

__SET($属性名,值)

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

__isset(属性名)

81d3ffdaf0a5

__isset(属性名)

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

__unset(属性名)

81d3ffdaf0a5

__unset(属性名)

方法重载

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

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

__call($method_name , $argument)

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

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

81d3ffdaf0a5

__call($method_name , $argument )

接口

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

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

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

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

形式:

interface 接口名{

常量1;

常量2;

.........

抽象方法1;

抽象方法2;

}

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

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

81d3ffdaf0a5

接口

接口的作用

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

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

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

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

使用形式:

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

}

81d3ffdaf0a5

接口作用

类的自动加载

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

什么时候需要一个类

1 new一个对象的时候;

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

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

81d3ffdaf0a5

自动加载函数

使用条件

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 ){

//.......

}

81d3ffdaf0a5

自定义自动加载函数

对象的复制(克隆)

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

定义

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

81d3ffdaf0a5

对象的复制(克隆)

__clone 魔术方法

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

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

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

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

对象的遍历

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

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

//处理$key  $value

}

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

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

81d3ffdaf0a5

对象的遍历

PHP内置标准类

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

class stdclass{    }

81d3ffdaf0a5

stdclass

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

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

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

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

81d3ffdaf0a5

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

②null 转为对象 为空对象

81d3ffdaf0a5

内置标准类

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

81d3ffdaf0a5

其他 标量数据 转为对象

类型约束

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

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

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

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

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

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

81d3ffdaf0a5

类型约束

类相关的魔术方法

序列化与反序列化技术

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

$v1  = 100;

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

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

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

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

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

81d3ffdaf0a5

序列化与反序列化

对象的序列化和反序列化

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

81d3ffdaf0a5

对象的序列化

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

__tostring()魔术方法(常用)

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

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

81d3ffdaf0a5

__tostring

与类相关的方法属性

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

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

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

81d3ffdaf0a5

魔术常量

与类有关的系统函数:

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:  判断一个“变量”(对象,数据),是否是某个类的“实例”;

81d3ffdaf0a5

instanceof

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

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

81d3ffdaf0a5

static和self

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值