码迷,mamicode.com
首页 > Web开发 > 详细

合并_03php面向对象基础(4days)笔记

时间:2016-05-23 06:44:46      阅读:197      评论:0      收藏:0      [点我收藏+]

标签:

面向对象编程思想

编程思想,面向过程,面向对象!

?

例如完成学生报名系统!

?

  1. 学生报到。
  2. 学校登记。
  3. 学生缴费。
  4. 学校收费。
  5. 学生选择班级。
  6. 班级登录学生信息。

?

一个步骤一个步骤的完善即可!

每个步骤是一个函数,通过逐一调用这些函数完成任务!

?

?

分析以上所实现的步骤:

将一个业务逻辑拆分成各个过程,分别实现各个过程,从而达到整个业务逻辑实现的目的!

称之为面向过程,类似于动词的罗列!是最基本的编程方案!

?

?

?

发现:

程序的最终目的,都是要解决真实的业务逻辑!

而且现实的业务逻辑,都是动作的主体在发出动作而不是动作独立出现的

?

现在面临的问题:

面向过程的编程方式,将一个罗拆分各个步骤之间组合,弱化了主体概念,主要强调步骤,和动作的概念!

而现实的业务逻辑都是由各个主体支配发生的,主体不可缺少!

?

导致:使用面向过程所编写的程序与真实的业务逻辑,逻辑关系不完全一致!从而使得面向过程的程序,不能完全的描述出真实的业务逻辑!

?

因此,如果希望使用计算机程序语言,更完善的描述去描述真实业务逻辑,明显,应该是计算机语言世界内,所有的动作多应该有主体发出!

上面的思想,就是面向对象的编程思想:是计算机解决问题的方式,尽量于现实的逻辑一致,现实的一个实体(人,物,事),应该映射成计算机语言内的一个对象!最终是计算机能够处理现实世界所有的业务逻辑!

技术分享

?

因此,如果需要使用面向对象的思想实现以上的报名流程,应该:

  1. 分析,有哪些实体,参与了该业务逻辑

学校,学生,班级

  1. 通过计算机语言,实现以上三个实体

得到三个对象!

?

  1. 为上面的三个对象增加上相应的能力!

?

  1. 使用对象,调用相应的能力,从而实现业务逻辑!

?

?

面向对象是解决复杂业务逻辑的唯一出路!

?

面向对象的基本操作

基本概念

对象,object,对应现实逻辑中的一个实体,是一个实体在计算机语言的一个表示。是一个数据,与数据的操作的集合体!

属性,property,对象的数据

方法,method,对象的操作

对象怎么来的?通过实例化类而生成!

类,class,使用计算机语言对一类事物的抽象。类似于图纸!用于规定某类对象的结构,但是本身不是具体对象。

实例化,instance,依据类的抽象定义,形成对象的操作,称之为实例化!

?

//昆虫,一个定义,一类动物的抽象的概念!

基本语法

声明类,class

使用关键字 class 即可!

技术分享

需要指定,该类下的实体(对象),应该有哪些特征,哪些属性,哪些操作!

例如,我们声明一个学生对象,需要先来学生类:

?

数据,称之为属性,property,属于对象(类)的变量。

操作,称之为方法,method,属于对象(类)的函数。

在声明成员时,不能直接使用变量,需要使用关键字来声明

技术分享

?

实例化类得到对象,new

使用关键字 new 即可

技术分享

技术分享

技术分享

实例化好后,典型的应该保存在变量内:

技术分享

?

我只需要设计图纸(定义类),不需要参数实力话的过程。

一个类可以被实例化多次!

技术分享

?

操作对象

?

使用 ->操作符,利用对象,访问其成员!

技术分享

访问属性

$object->stu_name;

注意,属性名前没有$。

技术分享

对当前某个对象的属性的操作,只会影响当前对象:

技术分享

技术分享

?

访问方法

对象->方法名();

技术分享

?

?

如何在方法中,访问对象,$this

$this,这个,这个对象。调用该方法的对象!

?

$this 就是一个方法内的局部变量!特殊在,方法被对象调用执行时,php会自动确定是哪个对象调用的该方法,会使用该对象为方法内的$this赋值

技术分享

技术分享

?

?

tip:public,是一个访问控制修饰符,适用于控制成员(属性和方法)的访问问题!protected,private。

?

?

测试:利用面向对象编程的语法,实现学生报名的业务逻辑:

?

?

构造方法,__construct()

在实例化类得到对象时被自动地调用!

主要承担的工作是初始化对象属性!

?

对象的属性初始化

典型的,只要得到了对象,对象的属性就应该被赋予新的值!

?

如果某些属性,在对象出现时,可以被设置为某些特定的值。就可以在声明类时,为声明的属性设置默认值!

技术分享

?

此处的属性的默认值,类似于参数,只能用已有值或者常量作为默认值。

技术分享

?

?

还是需要很多属性初始化!

此时应该?

将初始化的工作,声明成一个方法,得到需要被初始化的数据,在方法内,对当前属性进行初始化的工作:

技术分享

?

此时,在实例化对象后,调用该方法:

技术分享

此时可以完成初始化!

?

如果可以在new实例化时,自动地调用上的init方法,则手动步骤也可以省略!

?

PHP会在实例化对象时,自动调用一个叫 __construct()的方法!

技术分享

?

此时,如果该方法需要传递参数,则需要通过实例化时,在new cloass_name()以实参列表的形式,传递!

技术分享

?

?

如果没有定义__construct()可以不用执行!

但是一旦定义了构造方法,那么构造(实例化)的过程,一定要包括这个调用构造方法的过程(构造方法一定会执行)。

?

TIP:有时也称,实例化对象为构造对象!

?

构造方法可以自动被调用!

?

?

注意

  1. 构造方法可以是一个别的名字

一个与类名相同的方法,也可能是构造方法!

技术分享

?

此时会出现,同名与__construct同时出现的问题,__construct()会执行!

技术分享

典型的兼容性的写法!防止PHP4代码运行在PHP5的服务器上的一个兼容的做法!

技术分享

?

  1. 在new class_name时:

new Student

new Student();

取决于是否存在构造函数的必要参数!

?

?

析构方法,__destruct

与构造方法相对,表示在对象被销毁时,自动调用的方法!

对象被销毁,但是对象所占用的资源不一定完全被销毁!

?

在对象被销毁时调用,作用是,用于释放对象所占用的额外资源!而不是对象本身!

?

技术分享

unset($object)

技术分享

?

析构:

技术分享

技术分享

并不是非要有析构方法,看业务逻辑!

?

?

注意:

1对象在什么时候被销毁?

在用户脚本结束后,所有的资源包括对象都被销毁!

技术分享

2保存对象的变量被提前unset!

技术分享

  1. 保存对象的变量,被赋予了一个新的值!

技术分享

技术分享

?

?

预习

静态成员,static

::

类常量

self

?

继承,重写,访问权限控制

?

作业

设计一个数据库的操作类MySQLDB

?

要求:

  1. 在实例化对象时,就能够连接上数据库
  2. 在销毁对象时,关闭数据库
  3. 在实例化时,同样要求,设置连接字符集
  4. 实例化时,选择默认数据库

注意:类只是一个图纸,内声明的属性,在没有实例化对象时,是没有真实存在的!只有在实例化对象后,才会真实存在于对象内!

?

?

分析:MySQDB,的作用?

一个工具,项目中,凡是需要操作数据库,使用该工具完成!

?

设计:

应该完成那些功能,从而得到需要哪些属性!

需要的数据:主机,端口,用户,密码,字符集,默认数据库

技术分享

?

需要在构造对象时,将以上的属性,设置好!

增加一个构造方法 __construct,可以接收上面的参数!

如果一个方法或者函数参数过多,或者参数不能确定时:会选择使用数组的形式完成处理:

技术分享

?

在构造方法内,先完成对属性的初始化!

技术分享

?

连接数据库

使用当前对象的link属性,保存当前的连接资源!

技术分享

?

提示:写代码时,应该将一个独立功能封装成独立的部分,在其他地方如果需要,再对该功能进行调用!目的提高代码可重用性!

技术分享

技术分享

?

?

设置字符集

增加一个方法用于执行 set names charset ,在构造方法内调用!

技术分享

?

选择默认数据库

增加一个方法,用于执行 use dbname SQL语句!

在构造方法内调用即可

技术分享

?

测试:

技术分享

?

?

升级:对参数选项增加一个默认值的概念,类似于端口,编码,可以在常规情况下实例化时省略!

在构造方法内,对属性初始化时,对默认值做处理:

技术分享

技术分享

?

类的静态成员,static

?

场景:

记录学生的数量!

?

当有学生类,每个学生类对象,就是一学生!

?

实例化一次,多出来一个学生。销毁一次少一个学生!

?

定义一个计数器,构造方法中数量+1,析构数量-1~

?

如何定义这个计数器?

不能直接用属于对象的属性,每个对象所独有的!

显然,应该找一个对象所共有的数据?

构造方法静态局部变量,也是不行,原因是析构不能用!

显然,应该找一个能够被对象所共有并且能够在多个方法内使用的变量?

使用全局变量即可,在方法内,是可以通过$GLOBALS访问到全局变量的!

技术分享

?

此时,站在业务逻辑的角度分析下,是否合理?

全局变量不应该属于任何的对象或者类。$count 与 Student没有丝毫的逻辑上的联系!

?

显然,应该找一个能够被对象所共有并且能够在多个方法内使用的变量,还应该与当前的对象类有逻辑的关系的数据?

可以使用类的静态成员!

?

静态成员,指的是逻辑上被所有的对象所共享,属于类的成员称之为类的静态成员!

技术分享

分成静态属性和静态方法

保存数据的是静态属性,执行功能的静态方法!

声明

额外增加一个 static 关键字!

属性:

技术分享

方法:

技术分享

?

访问

->访问对象成员

?

因此,应该使用类访问,

类 :: 成员!

::,静态访问符,类访问符(范围解析操作符)

在构造方法中,访问到,++!

技术分享

技术分享

类似于$this,同样存在一个self关键字(注意没有$),在类中,代表当前类!

$this:这个对象, $this->

self:类自己,self::

技术分享

?

?

注意

  1. 访问上,静态成员只能使用::静态访问符号访问!

典型的,::前应该是类,类内可以使用self。

但是,php支持: 对象::静态成员!

技术分享

尽量不要这么写!

?

  1. 访问上,静态成员使用类访问,而非静态成员使用对象访问。

?

但是,问题出现在方法上!

测试1,使用类访问,静态与非静态方法:

技术分享

测试2,适用对象访问:

技术分享

结论:‘无论是静态方法,还是非静态方法,都可以使用类或者对象来访问。那么静态方法与非静态方法的意义在于哪里?

现象的原因:方法是可执行性代码的集合,针对多个对象都是一致的!

技术分享

区别在哪?

在于$this的使用上!

只有在使用对象调用非静态方法时,才可以使用$this!

静态静态方法,无论如何也不能对$this做处理

而非静态方法,只有确定了对象,才能确定$this的值!

?

?

在使用类调用对象方法时,应该注意什么问题?

?

?

?

类常量,const

在类内定义,属于类的常量!

?

定义

使用关键字const声明!

技术分享

而且,没有访问修饰限定符。

?

访问

使用类访问,与访问静态成员类似:

类::常量名.

技术分享

?

类中保存数据:

类常量,静态属性。

?

?

总结

类中,一共只有5种语法:

属性,方法,静态属性,静态方法,类常量

?

?

继承,extends

?

技术分享

?

书,与电话都有共同的属性,可以提取!

技术分享

在书,与电话中不用写:

技术分享

?

怎么才能在Book类对象中,是哟个Goods类所定义的属性呢?

?

使用继承:

定义

继承:如果一个对象A,使用了另一个对象B的成员,那么我们就称A对象继承了B对象!

?

语法

使用关键字 extends 让一个类继承自另一个类!

技术分享

技术分享

?

tip:继承概念体现在对象上,语法体现在类上!

?

此时,特定的称谓:

Goods:父类,基础类!

Book:子类,扩展类!

?

?

语法意义就是,面向对象语法中的,代码的重用!

?

单继承

?

指的是,一个类,只能存在一个父类(基础类),不能同时继承多个类!

技术分享

?

技术分享

?

?

instanceof,是否是某类实例

技术分享

体现:一个对象如果是子类的实例,同时也是父类的实例!(实例,通过该类实例化的对象)

?

?

?

重写,override

是个现象!

技术分享

如果子类,与父类,出现同名的成员(属性方法),则在实例化子类对象时,只会得到子类中定义的成员,称之为重写!

例如,方法重写:

技术分享

?

?

parent,父类

一旦重写,父类代码就不会在执行了!

?

但是有些方法是一定会重写的!

典型的构造方法:

技术分享

?

技术分享

怎样才能调用父类的构造方法呢?

?

parent,关键字,表示父类的意思!用于在当前类中,强制调用父类成员!

典型的做法,将参数传递到子类的构造方法中,再在子类中,强制使用parent关键字,调用父类的构造方法

技术分享

?

注意:self,parent,$this的区别:

self::????????当前类本身

parent::????当前类父类

$this->????当前对象。

?

技术分享

?

?

$this的确定

看上面的parent,或者是父类名:

技术分享

与:

"只有在使用对象调用非静态方法时,才可以使用$this!

静态静态方法,无论如何也不能对$this做处理

而非静态方法,只有确定了对象,才能确定$this的值!"

?

$this的或的基本原因:

  1. 哪个对象调用方法,方法内的$this就是那个对象!
  2. 对象环境,是可以向下传递的!

如果当前方法内,已经确定了对象环境。在该方法内,如果出现了静态调用非静态方法,此时当前的对象环境,会传递到被静态调用的非静态方法中!

技术分享

?

?

?

问:$this永远代表所在类对象么?

不是!

?

访问修饰限定符,public,protected,private

public,公共的

protected,保护的

private,私有的

?

用于描述,一个成员(属性,方法)在哪里才能被访问的!

?

注意:

PHP是采用类的概念,进行成员的限制访问的!

PHP将访问的代码,分成三大区域:类内类外继承链上类内!

?

是根据:

成员在哪里定义成员在哪里访问来决定类内,类外还是继承链上类内!

以属性 $property为例:

技术分享

技术分享

?

?

public

公共的,指的是,成员在本类内,继承链上的类内,与类外,都可以被访问!

技术分享

?

?

protected

保护的,指的是,成员在本类内,继承链(子类,父类)上的类内可以被访问

技术分享

?

private

私有的,指的是,只有本类内,可以访问!

技术分享

?

?

?

如何选择:

一个原则,尽量体现封装性。封装性,指的是,尽量隐藏内部实现,而仅仅开发外部操作接口!

语法上,就是,将不需要外部使用的属性,方法,都私有化(保护化),而仅仅留下一些必要的公共方法!

?

?

注意

  1. 重写的问题,一定要先明确访问的究竟是哪里所定义的!

技术分享

  1. 私有成员的重写问题。

私有成员不能被重写。意味着,在相应的私有属性定义的类中,才能访问到相应的私有属性!

技术分享

?

注意,在处理私有属性时,一定要确定其定义位置!

?

建议是

如果需要通过继承,你就使用保护的,少用私有的!

在没有继承时,尽量使用私有的!

?

?

  1. 在重写时,如果重写成员的访问级别不一致。

子类的级别比父类的级别,相等或者弱,可以!

强,不行!

技术分享

?

?

  1. 兼容性的问题

早先的 php的面向对象不完善,没有访问控制!

在声明属性时,使用 var 关键字!

声明方法时,什么都不使用!function

?

为了兼容,上面的做法还是可以使用!

?

var,function。访问权限都是 public的!

技术分享

?

?

冒泡排序

相邻的两个数比较,大数向后走!

模拟

待排序序列:

24

11

67

10

9

23

45

11

24

67

10

9

23

45

11

24

67

10

9

23

45

11

24

10

67

9

23

45

11

24

10

9

67

23

45

11

24

10

9

23

67

45

11

24

10

9

23

45

67

11

24

10

9

23

45

67

11

10

24

9

23

45

67

11

10

9

24

23

45

67

11

10

9

23

24

45

67

11

10

9

23

24

45

67

???????

?

?

明显,需要N-1轮就可以排序出来结果!

每轮内,需要对余下的元素依次做相邻的元素之间的比较!

?

计算关系:

$total = 7;

轮数

参与比较次数

比较

?

1

6

0,1|1,2|2,3|…|5,6

0-(7-1)-1

2

5

0,1|1,2|…|4,5

?

3

4

0,1|…|3,4

?

。。。

。。。

??

6

1

0,1

?

?

公式:

比较次数 = 总元素个数-轮数!

?

其次,需要控制那两个元素参与比较?

确定第一个参与比较的元素即可:

从0 到总元素个数-1-当前轮数

?

交换元素位置,找到第三个变量!

?

编程实现?

双层循环,外层比较轮数,内层控制比较元素下标!

技术分享

?

排序就是消灭逆序的过程!

?

预习

final,抽象,接口

序列化

自动加载

单例模式,工厂模式

作业

  1. 要求升级mysqldb,尽量体现封装性!
  2. 升级mysqldb,提取执行SQL的方法,凡是执行SQL,都需要调用该方法实现!
  3. 要求增加 fetchAll的方法,功能时得到一条查询类的sql语句,返回所有的结果数组!

技术分享

4,练习,比赛列表其他都是mysqldb来完成!

作业回顾

mysqlDB的封装性

技术分享

?

都封装起来了,需要对其修改,或者获取去信息,应该怎么办?

技术分享

?

为,需要在外边访问的成员属性,增加一对接口(公共)方法,便于操作!

技术分享

?

?

原则

禁用所有,开放特定!

?

?

提取执行sql语句的方法!

技术分享

?

在执行SQL时,使用该方法:

技术分享

技术分享

?

?

fetchAll

技术分享

?

技术分享

?

?

类:实例化对象

类:调用其静态成员

类:作为其他类的基础类,被继承!

?

两大功能:

1,实例化对象。2,基础类被继承

?

存在两种特殊的类,功能单一!

  1. 只能实例化对象,不能被继承。
  2. 只能被继承,不能实例化对象。

?

final类,final方法

final类

final,最终,在继承链条上最末的一个类!其下不能再出现子类,意味着不能被继承!

?

例如,认为,Book类的对象就是所有图书对象,不能再出现故事书,小说等等书的子类!

?

技术分享

final,并没有增加额外的功能!意义是,在语法上限制某个类不能被继承!从而保证数据的完整性!

?

final方法

final关键字还可以限制方法!

可能出现final方法!限制方法是否能被重写!

技术分享

抽象类,abstract类

抽象类:包含了抽象方法的类称之为抽象类,不能用于实例化对象,只能被继承!

抽象类,不完整的类,由于包含了不完整的方法。

不完整的方法,也叫抽象方法,指的是没有方法体的方法,称之为只有方法的声明,而没有方法的实现的方法称之为抽象方法。也就是不完整的方法!

技术分享

?

需要使用关键字 abstract来声明这个抽象方法与抽象类!

?

技术分享

不能实例化对象

技术分享

?

注意:抽象类是可以包含其他任何正常的成员的,在此基础上,增加了内部的抽象方法!

并不是抽象类中只能包含抽象方法

?

只能被继承

技术分享

但是,继承时,要求,如果子类不是抽象类,那么继承的抽象方法,要被实现(被加上方法体)才可以!

技术分享

?

使用意义

可见,抽象类,可以规定其非抽象子类,必须要存在的相应成员方法!

可以规定,子类中都必须存在,但是可以不同的方法!

技术分享

?

?

几个概念:

抽象:abstract,不完整的意思!举目张刚的意思!

实现:implement。将方法完整化!

?

?

接口结构,interface

接口,指的是对象的公共方法。

也有一种接口技术,定义一个接口结构,用于限制一个类(对象)因该具备的公共方法(接口方法)!

?

?

语法:

?

声明

使用关键字 interface声明一个接口结构!

技术分享

注意,接口内只能包含公共的抽象方法(不完整的方法)!

?

使用

使一个类来实现接口内所定义的所有接口方法(公共方法)

实现,使用关键字:implements来完成

技术分享

明显,实现该接口结构的类,就包含了接口中定义的抽象方法,两个选择,1,定义成抽象类,2是实现接口方法!

?

?

类似于抽象类,比较与接口的区别:

  1. 抽象类与普通类之间是继承关系!

普通类继承抽象了,第一可以得到抽象类中的已有的常规成员,第二才需要实现抽象方法(也不一定是public的)

  1. 接口与普通类之间是实现关系!

普通类实现了接口,只能将其没有实现的公共方法实现!

?

  1. 接口只用于定义公共的方法!而抽象类,什么都可以有!

?

典型的使用:

?

?

多实现

一个类,可以同时实现多个接口

技术分享

?

?

?

接口可以定义常量

技术分享

?

?

辨别?

  1. 接口是不是类?

接口不是类,接口就是独立的一种结构,适用于限制类的结构!但是可以理解成"接口类似于一个所有的方法都是公共的抽象方法,而且没有其他成员的抽象类",但完全不是一个概念!

class_exists();判断一个类是否存在?

  1. php是单继承,怎么实现多继承?

    "可以通过接口的多实现来模拟"

    不能实现多继承!

技术分享

?

?

类文件的载入-自动加载机制

项目中如何管理大量的类的定义?

典型的,每个类,独立的创建一个文件,用于保存定义该类的源代码!使用时,将该文件载入即可!

技术分享

此时,类文件的命名为:

类名.class.php

?

此时,面临一个类文件很多,某个功能需要使用其中不分类:

如何合理方便载入?

?

老办法:

将载入类的代码,放在一起:

技术分享问题是,会有类的额外加载!

?

现在的载入类文件的方式是?

按需加载

?

在需要某个类时,如果该类没有被加载,则加载定义该类的类文件!

?

判断当前类是否已经加载?

该类在哪个文件中?

什么时机执行上面的操作?PHP本身解决

?

此时可以使用PHP的类文件,自动加载机制完成!

?

自动加载机制

当需要一个类,当时并没有找到该类的定义,此时,PHP核心(Zend Engine),会自动尝试调用一个叫:__autoload()的函数。与此同时,会将当前所需要的类名作为参数,传递到__autoload()这个函数中。

?

默认是没有这个函数的,需要用户自己定义!

?

因此,用户脚本,需要完成定义该函数:

该函数应该有个形参,用于得到当前所需要的类名!

技术分享

?

此时,我们只要,完成该函数,利用得到的类名,将类名所对应的文件载入即可!

技术分享

?

分工:

用户脚本:定义函数,接收需要的类名作为参数,函数需要实现通过类名找到类所在的文件,将其载入即可!

PHP核心:判断是否需要类,并且判断该类是否已经载入了,如果需要但是没有载入,则尝试调用用户定义的__autoload()函数,并将需要的类名传递即可!

?

?

分析:

__autoload函数获得是类名

而载入的是类的定义文件

因此,自动加载机制的大前提:必须要能够通过类名,推导出,类定义所在的文件才可以!

因此,要求大家在定义类文件时,要有规律!

?

类文件 = F(类名)

?

?

序列化,反序列化

串行化,反串行化

?

场景。

数据的持久性保存!

?

例如,将数据保存在文件:

向文件写入数据:

写入的长度 = file_put_contents(‘文件‘, ‘数据‘);

技术分享

从文件读取数据:

数据 = file_get_contents(‘文件‘);

技术分享

?

?

在数据保存,面临一个问题:

数据格式的问题。

?

PHP的数据有八种类型之多,文件只能存字符串!!

?

一旦数据类型不是字符串类型!就会导致数据不能原样保存,不能取得原始数据!

?

因该如何解决?

任何形式的数据,都可以存储到文件中,并且,在取出来时,原样得到数据!

?

在保存,与读取时,对数据进行转换与反转换!

技术分享

?

?

序列化,serialize

原始数据转成能够记录原始数据信息的字符串!

技术分享

技术分享

技术分享

?

反序列化,unserialize

通过序列化的字符串结果,将原始数据还原!

技术分享

?

?

只有在涉及到,数据需要被,存储,或者传输时(),需要对数据进行序列化!

?

?

注意的数据类型都可以被序列化与反序列外。资源是例外!

例如:

技术分享

其他可以!

技术分享

技术分享

?

?

对象的序列化与反序列化

  1. 在反序列化时,需要找到该对象所属的类的定义才可以,否则会变成__PHP_Incomplete_Class类的对象,不是原来的对象:

存入:

技术分享

读取:

技术分享

?

因此,只要在反序列化之前,将类载入即可!

技术分享

?

?

  1. 反序列化,也会触发自动加载机制。

技术分享

?

?

  1. 在序列化时,可以自定义需要序列化的属性名单!

通过对象的特殊的方法__sleep()

该方法会在对象被序列化时,自动调用,不需要参数,需要返回一个数组,每个元素,表示一个属性名,数组内存在的属性名,就会被序列化。反之则不会被序列化!

技术分享

?

  1. 在反序列化时,可以自动再次执行某些代码,从而完成某些资源的初始化!

通过对象方法:__wakeup()方法

会在对象被反序列过程中自动调用,所负责的功能,执行反序列话(醒来之后)的初始化工作!

技术分享

?

?

?

总结:

__construct

__destruct

__sleep

__wakeup

?

php自动调用,用户脚本只需要定义。在特定的功能调用特定的方法!

总称为:魔术方法;

?

?

?

对象的拷贝

技术分享

对象之间的赋值,只有引用传递,没有值传递!

保存对象的变量内,保存的不是对象本身,而是对象的标识!

技术分享

?

导致的结果,不能通过赋值的方式,使用旧对象,得到新对象!

?

对象的克隆

克隆,使用一个已有对象,得到一个属性一致的新对象

使用关键字 clone 来实现

技术分享

?

典型在克隆时,一定会出现某些属性时用于区分是否是克隆出来的!

?

意味着,在克隆出来新对象时,要为新对象增加一些额外的标识才可以!

此时,在执行clone时,会自动调用新对象的魔术方法 __clone,去完成克隆对象的额外的初始化工作!

技术分享

注意,$this是新对象!

?

预习

设计模式,单例模式,工厂模式

重载,属性方法重载

魔术方法

反射机制

作业

  1. 增加mysqldb类的fetchRow方法

类似于fetchAll,执行一条查询类的sql,返回符合条件的第一条记录!

?

$sql = "select * from select-student where id=10";

$row = $db->fetchRow($sql);

$row = array(‘id‘=>10, ‘stu_name‘=>‘张无忌‘, class_id=‘10‘);

  1. 增加mysqldb类的fetchColumn方法

类似于fetchRow,执行一条查询类的sql,返回符合条件的第一条记录的第一个字段值!

select count(*) from student

$result = $db->fetchColumn($sql);

$result = ‘23‘;

?

?

3,使用mysqldb工具类,全面改善match功能!

单例模式

单例,单个实例。设计模式的一种,通过一种语法的设计,保证类(对象)上具有某些特征,这样的一种语法实现,就可以称之为设计模式!

其中,设计可以保证一个类,有且只有一个对象,这种设计模式就称之为单例模式!

单例模式的作用,单例的设计,是适用于使用一个对象可以完成所有业务逻辑的类

?

典型的实现,在类上,做限制:三私一公!

某个类只要实例化一次就可以完成所有的业务逻辑!

但是实例化多次也可以。

?

显然,应该保证对象被实例化一次,从而节约资源空间!

?

例如,当前的MySQLDB类!

?

那么,如何去设计这个MySQLDB类,从而达到保证该类有且只有一个对象

原因就是使用者,可以无限次地去实例化这个类new!

技术分享

?

解决步骤,三私一共

  1. 限制,用户无无限制执行new!

在实例化的过程中,需要执行构造方法,如果构造执行不成功,那么实例化过程失败!

因此:将构造方法,私有化(保护化),可以保证在类外进行实例化的工作都会失败

技术分享

  1. 类,不能实例化了,不能在类外实例化了!可以在类内实例化,类内执行new操作!

?

因此:在类中,增加一个公共的静态的方法,在方法内,执行new实例化类对象!

技术分享

?

  1. 看似又回到了原点,可以无限制的调用getInstance得到任意多个对象!但是此时得到对象都需要经过 getInstance,我们可以在getInstance内,增加限制,使用户得到对象的改变!

方案如下:在实例化好对象后,将对象存起来,下次再执行时,判断是否已经有保存的,有了,直接返回已经存在的,没有,实例化后,保存起来,再返回!

增加一个私有的静态属性,在 getinstance内做判断

技术分享

?

此时,无论调用N次,getinstance,都得到一个对象:

技术分享

?

?

  1. 此时,还可以通过克隆来得到新对象!

私有化__clone()方法

技术分享

?

?

?

注意,在单例时,为构造方法传参的问题:

?

?

?

在项目的设计层面解决单例的问题

?

增加一个实例化的方法(函数)

希望,用户如果想要得到单例对象,就通过调用该函数完成!

?

技术分享

?

?

优点,灵活,可以针对多个类同时实现单例,而且,类还可以回归到非单例的效果!

?

重载

重载,重新加载!

技术分享

?

重载,overload,指的是php对当前对象的不可访问成员的处理方式!

其中,不可访问:指的是两种,不存在的和受到访问控制访问不到的!

默认的处理方式:

  1. 针对不存在的属性:

自动增加属性为公共的属性!

  1. 针对访问权限限制的:

    技术分享

?

上面的默认的处理方式都是可以有更改的余地!

?

属性重载的魔术方法

属性的重载处理,需要使用php提供的魔术方法完成

技术分享

因此,有四个魔术方法,用于分别处理上面的情况:

__set();

当为不可访问的属性赋值时,会被自动调用

会得到两个参数,当前操作的属性名,和属性值!

技术分享

典型的,__set的作用,用于严格控制对象结构,和批量处理可以被修改的属性!

技术分享

?

?

__get();

当访问不可访问的属性时,会被自动调用

需要的参数是:一个,为当前操作的属性名

技术分享

?

__unset()

在删除一个不可访问的属性时,可以自动被调用!

需要一个参数当前操作的属性名。

此时就可以利用业务逻辑完成属性的删除处理!

技术分享

__isset();

在判断一个不可访问的属性是否存在时,被自动调用

需要一个参数,属性名

注意,次函数需要返回true,或者false,表示属性是否存在:

技术分享

?

?

在很多其他语言中,重载,指的是重复加载!

技术分享

?

方法重载的魔术方法

__call()

当访问一个不可访问的对象方法时,会触发当前的魔术方法!

技术分享

此时会触发:

需要的参数时:

2个参数,第一是当前的方法名,第二是调用时使用的实参列表!

技术分享

?

典型的作用,

  1. 给出友好的提示
  2. 执行默认操作!

    技术分享

static __callStatic()

与 __call类似,当静态调用一个不可访问的方法时,会自动执行!

技术分享

?

?

魔术方法,magic method

在特定的情况下,会被自动调用的方法,通常负责完成某块独立的功能的方法称之为魔术方法!特点:1,需要用户脚本定义,不定义不执行!2,命名方式都是以__开头!

?

总结:

__construct

__destruct

__sleep

__wakeup

__set

__get

__isset

__unset

__clone

__call

__callStatic

?

__autoload()//魔术函数

?

?

?

__invoke()

将一个对象,当作函数调用时,会触发该对象的__invoke()方法,由此方法,就可以调用,没有该方法就不能调用!

?

回想匿名函数

技术分享

$say中是啥?对象!

技术分享

语法是调用对象的语法?

技术分享

为什么,匿名函数对象(ClosureL类对象)可以,但是普通类对象不行?

技术分享

?

__invoke是 php实现匿名函数不可或缺的部分!

?

此时,也可以传递参数,为对象传递参数,就是为invoke魔术方法传递参数!

技术分享

?

__toString()

转换到字符串的意思!

当将对象当作字符串使用时,会自动调用该对象的魔术方法!

技术分享

如果此时,存在toString 魔术方法,即可以完成转换。

toString的返回值,就是转换的结果,一般转换对象的标志性的属性即可!

技术分享

?

?

?

静态延迟绑定,static

>=5.3

问题:

  1. $this永远代表所在类的对象?不是
  2. self用于代表所在类么?

    是,永远代表所在类的对象!

    ?

看逻辑:

技术分享

显然,当前的逻辑不是十分完善!

?

此时,应该是表示当前类的关键字,最好应该在调用时决定最好!(self不能做到)

?

此时,采用一个新的关键字,代表当前类,与self不同,在于是运行时调用时决定,而不是在类编译时就确定好了的!

关键字是: static。

技术分享

?

?

?

总结:

static关键字的功能:

  1. 声明静态局部变量
  2. 声明静态成员
  3. 当前类,运行时的当前类!

?

类中,可以表示类的关键字:

self,所在类

static,调用类

parent,父类

?

?

参数类型约束

约束函数,或者方法类参数的类型,只能是某个类的对象!

?

php是弱类型,变量可以存储任意类型的数据!

函数,方法的参数也是可以接受任意类型!

?

但是参数,可以被规定为,某个类的固定对象!

技术分享

在参数前增加类名即可!

?

注意,只支持类名!

技术分享

?

?

还支持数组!

技术分享

?

?

对象的遍历

对象是一个集合数据类型!

简单的遍历,foreach

foreach,可以遍历对象

遍历对象,是依次获得对象拥有的属性的信息!

技术分享

留意,访问修饰可以影响!

?

自定义遍历,iterator,迭代器接口

场景:在遍历班级时,就相当于,遍历的班级的所有学生,而不不是遍历班级的所有属性!

技术分享

?

此时,需要使用接口编程实现。

?

foreach时,php回去判断当前所遍历的对象的类,是否类实现一个叫 iterator(迭代器) 接口!

不是的话,就会依次得到对象每个属性!(简单遍历)

是的话,会在foreach执行时,通过调用接口内规定的各个方法来完成这个遍历!

?

两个问题:

foreach的流程:

技术分享

Iterator接口的内容:预定义的!php定义好了的!

技术分享

显然,php的foreach的五个重要的步骤,依赖于接口中定义的5个方法!

技术分享

?

编程实现,是需要遍历学生信息:

  1. 类要实现Iterator接口

技术分享

2依次完善抽象方法

技术分享

?

?

常用的对象,类函数

技术分享

is_object();

class_exists();

interface_exists();

get_class();

get_parent_class();

?

get_class_vars();得到类的变量(属性)

get_class_methods();得到类的方法

技术分享

?

get_declared_classes();得到所有已经定义的类!

技术分享

可以见,有自定义类,和预定义类!

stdClass,内置的标准类!

技术分享

__PHP_Incomplete_Class

Closure

?

?

魔术常量

__CLASS__,当前类名。注意:可以new self不可以new __CLASS__。

__METHOD__,当前方法名。区别__FUNCTION__。

技术分享

__FILE__

__DIR__

__LINE__

__FUNCTION__

?

?

面向对象的特征

封装,

?

继承

?

多态

?

?

快速排序

分治。分而治之!

核心思想:解决一个难度为N的问题,与解决2个难度为N/2 相比

?

冒泡解决 6个元素的问题?

需要比较几次?

5,4,3,2,1 = 15

?

冒泡 3 个元素的问题两次?

2,1 = 3

2,1 = 3

?

思路:

将整体的待排序序列,分割成两个部分!分割的原则,跳出一个参考元,将比参考元大的,放一起,比参考元小的放在一起!假设第一个为参考元!

技术分享

?

接下,再对,分割的两个子序列,再次分割!

直到所有的分割的待排序序列内,元素数量为一个或者0个!

?

技术分享

?

实现的时候,应该注意:1,选择参考元的问题。

?

编程实现:

递归实现!

递归点:

递归出口:待排序的序列元素个数为1或者0,则不需要再递归了!

?

步骤:

  1. 判断是否是需要再次递归(递归出口)
  2. 选择参考元(第一个元素)
  3. 将数组分割成两个部分。
  4. 递归对分割的两个部分进行分别排序
  5. 将小于与参考元与大于三个部分合并起来!

?

技术分享

作业

  1. 将MySQLDB改写成单例的三私一共的!
  2. 总结所有的魔术方法

名字

作用

触发时机

获得的参数

__set

属性重载,设置属性

不可以访问属性赋值

属性名字,属性值

????
????
????
????
????
????
????

?

面向对象所有的关键字:

关键字

功能

示例

?

New

实例化

New class_name;

?
????
????
????
????
????

?

  1. 思考题

一个10层楼,电梯。

每层的电梯门口,都摆放了一堆钱,但是数量不一致!

问题,从1到10.每层打开门一次,在10次中,可以去拿起一次钱!

问题,怎样才能拿到最多?

?

?

合并_03php面向对象基础(4days)笔记

标签:

原文地址:http://www.cnblogs.com/yizhinageyuanfang/p/5518557.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!