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

面向对象编程思想

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

?

例如完成学生报名系统!

?

  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次中,可以去拿起一次钱!

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

?

?

时间: 2024-10-13 11:28:06

合并_03php面向对象基础(4days)笔记的相关文章

大话设计模式学习笔记——面向对象基础

前言 好记性不如烂"笔头"系列--大话设计模式学习笔记 目录 面向对象基础 面向对象基础 什么是类与实例 一切事物皆为对象,即所有的东西老师对象,对象就是可以看到.感觉到.听到.触摸到.尝到.或闻到的东西.准确地说,对象是一个自包含的实体,用一组可识别的特性和行为来标识.面向对象编程,英文叫 Object-Oriented Programming,其实就是针对对象来进行编程的意思.类就是具有相同属性和功能的对象的抽象集合.实例就是一个真实的对象.比如我们属于'人'类,而个人就是'人'类

如鹏网学习笔记(二)面向对象基础

面向对象基础1,面向对象的三大特征:封装.继承.多态. 2,定义字段的方法和实例化类:和声明数组一样,类名 对象名 = new 类名(); 3,对象的引用传递:Person weiren = yzk; weiren指向对yzk当前所指向的对象. 4,null和成员变量.局部变量的不同初始化 1)null表示变量没有指向任何对象 2)对于一个为null的变量调用成员方法都会报异常NullReferenceException 3)值类型(ValueType):数据类型(int.long.double

C#面向对象基础(一)

面向对象这个词我很早就知道了,但具体是什么东西?什么是面向对象?一直以来都 不理解,只知道它有三大特征,即封装-继承-多态.直到学习完C#视频和看完设计模式 中面向对象基础后,对C#面向对象才有了一个大致的理解.下面这幅图是我对它的一个 宏观的认识. 一.基本知识 1.类成员 属性 C#不直接访问类的数据,通过get和set访问类中字段 方法 表示类的行为.方法可以构造,也可以重载 2.封装 每个对象都包含它能进行操作所需要的所有信息,这种特性就是封装 3.继承 如果两个对象A和B,可以描述为B

面向对象基础(class0425)字符串与集合

常用类库 学习.net就是学习它的无数个类库怎么用,先看两个简单的 String 字符串,不可变特性.字符串可以看成字符数组 属性 Length 方法 IsNullOrEmpty() 静态方法 ToCharArray() ToLower() string不可变性 ToUpper() Equals() 忽略大小写的比较 Join() 静态方法 Format () 静态方法 IndexOf() LastIndexOf() Substring() Split() Replace() Trim()  C

imooc’s html 基础教程笔记

imooc’s html 基础教程笔记 imooc’s html 基础教程 第一章 Html介绍 1.1 Html和CSS的关系 1.2认识html标签 1.3 标签的语法 1.4 认识html文件基本结构 1.5 认识head标签 1.6了解HTML的代码注释 2.1语义化,让你的网页更好的被搜索引擎理解 2.2 标签,网页上显示的内容放在这里 2.3 开始学习标签,添加段落 2.4 了解标签,为你的网页添加标题 2.5 加入强调语气,使用strong和em标签 2.6 使用span标签为文字

JAVA的面向对象编程--------课堂笔记

JAVA的面向对象编程--------课堂笔记 面向对象主要针对面向过程. 面向过程的基本单元是函数.   什么是对象:EVERYTHING IS OBJECT(万物皆对象)   所有的事物都有两个方面: 有什么(属性):用来描述对象. 能够做什么(方法):告诉外界对象有那些功能. 后者以前者为基础. 大的对象的属性也可以是一个对象.   为什么要使用面向对象: 首先,面向对象符合人类看待事物的一般规律. 对象的方法的实现细节是屏蔽的,只有对象方法的实现者了解细节. 方法的定义非常重要.方法有参

java基础学习笔记day01

java基础学习笔记day01 1.软件开发: 软件:按照特定顺序组织的计算机数据和指令的集合 开发:软件的制作过程 软件开发:借助开发工具和计算机语言制作软件 2.java概述: java之父:詹姆斯·高斯林 JDK:java开发环境 jre:java运行环境 JVM:java虚拟机 java跨平台是因为,JVM能在不同的平台运行,JVM是跨平台的 JavaSE:标准版 JavaME:手机端,物联网 JavaEE:企业版,互联网项目 3.java语言特点: 简单性 解释性 面向对象 高性能 分

HTML&CSS基础学习笔记15-合并单元格

合并单元格 之前的文章中,我们已经能够创建一个简单地表格了,如果我们需要把横向的某两个相邻单元格<td>或者纵向的某两个相邻单元格<td>合并,我们该怎么做呢?我们要知道的知识点如下: 1.标签<td>的[colspan]属性规定单元格可横跨的列数,即横向合并的单元格数: 2.标签<td>的[rowspan] 属性规定单元格可横跨的行数,即纵向合并的单元格数: 3.这2个标签也可以同时使用. 样式示例: 现在就来试试合并单元格吧: <!DOCTYPE 

面向对象先导学习笔记

面向对象先导学习笔记 经过了Python.C语言和数据结构的学习,感觉对于Java这门新学习的语言上手速度明显快了许多.在学习Java的过程中,个人觉得Java的语法规则在很大程度上与C类似,但是在设计程序和具体实现的过程中,更偏向于Python的思路,尤其是对于方法的调用和自带数据结构的使用方面. 数据类型的Java实现 Java自带了大量的数据类型,在完成作业的过程中,个人尝试通过手写二叉树完成问题,但是与Java自带的数据结构相比,无论是在稳定性和运行速度方面都有所欠缺.但是通过自己的摸索