pop和oop的区别?
面向过程化的开发(POP)
将软件分解成多个流程步骤的,依次按步骤操作,功能就可以实现。
过程化的弊端:不利于大型软件的开发,对于软件的扩展与维护都是比较困难的。
面向过程编程的最小的编程单元为:函数。
面向对象开发(OOP):
面向对象编程的最小的编程单元为:对象。
面向对象编程,将软件开发,从构建上分解成多个模块。
面向对象编程:适合开发大型的软件,这种方式利于软件后期的扩展与维护。
面向对象与面向过程的区别:
- 过程: 任务流程; 对象: 实现功能的模块或对象 有哪些。
- 过程: 适合小项目,需求基本固定; 对象: 大型项目,需要总是变化
- 过程:数据与编程是相分离的 对象: 数据是封装在对象中。
- 过程: 定义一个常量 define(“PI”,3.1415) 对象:const PI = 3.1415;
类和对象的区别?
对象是如何产生的?
物以类聚,人以群分。
一个类实例化后,产生了一个对象
代码: $obj = new 类名();
类与对象概念?
类:是对不同对象,它们共有的属性与行为的抽象化表示。 抽象化,一般不用它来实现功能。
对象: 一切可见或不可见的东西,皆对象。 具体的,可以实现特定的功能。
对象:由属性(静态信息)与方法(行为 动态信息)组成。
传值和传引用的区别?
传值 a 的 值 赋 值 给 a的值赋值给 a的值赋值给b,会给 b 这 个 变 量 开 辟 一 个 新 的 地 址 , 它 们 两 个 互 相 不 影 响 。 传 引 用 这 里 的 变 量 b这个变量开辟一个新的地址,它们两个互相不影响。 传引用 这里的变量 b这个变量开辟一个新的地址,它们两个互相不影响。传引用这里的变量d 与 c , 它 们 俩 个 指 向 的 是 同 一 个 地 址 , c ,它们俩个指向的是同一个地址, c,它们俩个指向的是同一个地址,d改变会影响 c , 同 理 , c,同理, c,同理,c改变也会影响$d
魔术方法?
当某种情况发生的时候,自动调用 的方法
__construct() :当new 一个类 产生一个对象的时候,自动调用 。作用:对象初始化。
__destruct():当前脚本结束时,会触发 __destruct(); 这种隐式的销毁对象;使用 unset()函数,手工的销毁对象的标识 $obj = new 类名
1、__construct(): 构造函数,new一个对象时,自动调用
2、__destruct(): 析构函数,当一个对象被销毁前,自动调用
3、__get():访问类中私有属性时,自动调用。传递读取的属性名,返回KaTeX parse error: Expected group after '_' at position 13: this->属性名 4、_̲_set():给类的私有属性赋…this->属性名);
6、__unset():使用unset()删除对象私有属性时,自动调用。传递删除的属性名,方法中执行unset($this->属性名);
7、__toString():使用echo打印对象时,自动调用。返回想要打印对象时,现实内容;返回必须是字符串;
8、__call():调用一个类中未定义或未公开的方法时,自动调用。传递被调用的函数名,和参数列表数组;
9、__clone():当使用clone关键字,克隆一个对象时,自动调用。作用是为新克隆的对象进行初始化复制;
10、__sleep():对象序列化时,自动调用。返回一个数组,数组中的值就是可以序列化的属性。
11、__wakeup():对象反系列化时,自动调用。为反序列化新产生的对象,进行初始化复制;
12、__autoload():需要在类外部声明函数。当实例化一个为生命的类时,自动调用。传递实例化的类名,可以使用类名自动加载对应的类文件。
面向对象三大特性
三大特性是:封装、继承、多态
1.封装性:
目的:保护对象的属性或方法不被修改。
实现方式:
访问控制来实现: public(公共,公开的),protected(受保护的) ,private(私有的)
访问控制 类内 子类 类外部
public yes yes yes
protected yes yes no
private yes no no
如果父类的方法是私有的,子类是不能继承的。
2.继承性:子类继承父类。
- 节省了一些代码,可以不重复写父类的属性或方法;
- 自身也可以实现功能上扩展;
- 子类也可以 重写父类的属性或方法,
实现方式: class 子类 extends 父类{}
php中的继承是 单继承,子类只能继承一个父类。
3.多态:就是指一个类实例的相同方法在不同情形有不同表现形式。
多态机制使具有不同内部结构的对象可以共享相同的外部接口。这意味着,虽然针对不同对象的具体操作不同,但通过一个公共的类,它们(那些操作)可以通过相同的方式予以调用。
面向对象6项原则
单一职责、里氏代换、依赖倒置、接口隔离、迪米特法则、开闭原则
1.单一职责
定义:不要存在多于一个导致类变更的原因。通俗的说,即一个 类 只负责一项职责。
优点:
1 )、可以降低类的复杂度,一个类只负责一项职责,逻辑简单;
2 )、提高类的可读性,提高系统的可维护性;
3 )、变更引起的风险降低, 变更 是必然的。
2.里氏代换原则
定义: 所有引用基类的地方必须能透明地使用其子类的对象,也就是说 子 类可以扩展父类的功能,但不能改变父类原有的功能。
3.依赖倒置原则
定义: 高层模块不应该依赖低层模块,二者都应该依赖其抽象;抽象不应该依赖细节;细节应该依赖抽象。
此处理解起来是最困难的,一般会在项目框架的搭建的时候用到,例如,业务逻辑层相对于数据层是高层模块,因为业务逻辑层需要调用数据层去连接数据库,但是要做到可扩展高复用,尽量不要让业务逻辑层依赖数据层,可以在数据层抽象出一个接口,让业务逻辑层依赖于这个抽象接口。
优点:
1 )、低层模块尽量都要有 抽象类或接口 ,或者两者都有。
2 )、变量的声明类型尽量是抽象类或接口。
3 )、使用继承时遵循里氏替换原则。
4.接口隔离原则
定义: 客户端不应该依赖它不需要的接口;一个类对另一个类的依赖应该建立在最小的接口上。
注意:
1 )、接口尽量小,但是要有限度 。对接口进行细化可以提高程序设计灵活性 是不挣的事实,但是如果过小,则会造成接口数量过多,使设计复杂化。所以一定要适度。
2 )、为依赖接口的类定制服务,只暴露给调用的类它需要的方法,它不需要的方法则隐藏起来。只有专注地为一个模块提供定制服务,才能建立最小的依赖关系。
3 )、提高内聚,减少对外交互。使接口用 最少的方法去完成最多 的事情。
5. 迪米特法则(最少知道原则)
定义: 一个对象应该对其他对象保持最少的了解。
场景: 类与类之间的关系越密切,耦合度越大,当一个类发生改变时,对另一个类的影响也越大 。
简单的理解就是高内聚,一个类的方法和属性能用私有的就尽量私有化。
注意:
1 )、只与直接的朋友通信,不要和陌生人说话。
2 )、过分的使用该原则,将导致系统复杂度变大。所以在采用迪米特法则时要反复权衡,既做到结构清晰,又要高内聚低耦合。
6.开闭原则
定义: 一个软件实体如类、模块和函数应该 对扩展开放,对修改关闭 。
场景: 在软件的生命周期内,因为变化、升级和维护等原因需要对软件原有代码进行修改时,可能会给旧代码中引入错误,也可能会使我们不得不对整个功能进行重构,并且需要原有代码经过重新测试 。
建议: 当软件需求变化时,尽量通过扩展软件实体的行为来实现变化,而不是通过修改已有的代码来实现变化。
PHP中的抽象类与抽象方法
1、什么是抽象方法?
没有方法体 {} 的方法,必须使用abstract 关键字修饰。这样的方,我们叫做抽象方法。
abstract function say(); // 抽象方法
2、什么是抽象类?
包含抽象方法的类就叫抽象类。抽象类必须使用abstract关键字修饰。
abstract class Person{}
3、抽象类的注意事项
① 抽象类可以包含非抽象方法;
② 包含抽象方法的类,一定是抽象类;
抽象类,并不一定必须包含抽象方法;
③ 抽象类,不能实例化。
(抽象类中可能包含抽象方法,抽象方法没有方法体,实例化调用没有意义。)
我们使用抽象类的目的!就是限制实例化!!!
4、 子类继承抽象类,那么子类必须重写父类的所有抽象方法。除非子类也是抽象类。
5、使用抽象类的作用?
① 限制实例化。(抽象类是一个不完整的类,里面的抽象方法没有方法体,所以不能实例化)
② 抽象类为子类的继承提供一种规范。子类继承一个抽象类,则必须包含并且实现抽象类中已定的抽象方法。
静态属性和静态方法
1、static
① 可以修饰属性和方法,分别称为静态属性、静态方法,也叫类属性、类方法;
② 静态属性、静态方法,只能使用类名直接调用。
使用"类名::
静
态
属
性
"
、
"
类
名
:
:
静
态
方
法
(
)
"
P
e
r
s
o
n
:
:
静态属性" 、 "类名::静态方法()" Person::
静态属性"、"类名::静态方法()"Person::sex; Person::say();
③ 静态属性、方法,在类装载时就会声明。先于对象产生;
④ 静态方法中,不能调用非静态属性或方法;
非静态方法,可以调用静态属性或方法;
(因为静态属性和方法在类装载时就已经产生,而非静态的属性方法、此时还没有实例化诞生)
⑤ 在类中,可以使用self关键字,代指类名。
class Person{
static KaTeX parse error: Expected '}', got 'EOF' at end of input: …(){ echo self::sex;
}
}
⑥ 静态属性是共享的。也就是new很多对象也是共用一个属性。
2、final
① final 修饰类,此类为最终类,不能被继承;
② final 修饰方法,此方法为最终方法,不能被重写!
③ final 不能修饰属性。
3、const关键字;
在类中声明常量,不能使用define()函数!必须使用const关键字。
与define()声明类似,const关键字声明常量不能带$,必须全部大写!
常量一旦声明,不能改变。调用时与static一样,使用类名帝爱用 Person::常量。
串行化与反串行化(序列化与反序列化)
1、串行化:将对象通过一系列操作,转化为一个字符串你的过程,称为串行化;
2、反串行化:将串行化后的字符串,再转为对象的过程,称为反串行化;
3、什么时候使用串行化?
① 对象需要在网络中传输的时候;
② 对象需要在文件或者数据库中持久保存的时候;
4、怎么实现对象串行化与反串行化?
串行化:
s
t
r
=
s
e
r
i
a
l
i
z
e
(
str = serialize(
str=serialize(duixiang);
反串行化:
d
u
i
x
i
a
n
g
=
u
n
s
e
r
i
a
l
i
z
e
(
duixiang = unserialize(
duixiang=unserialize(str);
5、__sleep()魔术方法:
① 当执行对象串行化的时候,会自动执行__sleep()函数;
② __sleep()函数要求返回一个数组,数组中的值,就是可以串行化的属性;不在数组中的属性,不能被串行化;
function __sleep(){
return array(“name”,“age”);//只有name/age两个属性可以串行化
}
6、__wakeup()魔术方法:
① 当反串行化对象时,自动调用__wakeup()方法;
② 自动调用时,用于给反串行化产生的新对象属性,进行重新复制;
function __wakeup(){
$this->name = “李四”;
接口
接口是一个特殊的抽象类。
接口中的方法都是抽象方法;
接口中不能定义属性。
接口中可以定义常量
接口中的抽象方法默认都是公开的。public , 如果写成 protected 或 private就是错的。
**接口的作用**:
在php中,是单继承的,而现实生活中是存在多继承的关系的。在php中借助接口来表达多继承的关系。
接口实现的是契约式编程:
* 在编写一个类之前,将这个类所具有的功能,
* 首先将每一个功能定义中接口,
* 然后通过类去 实现 接口,
* 这样我们编写的类就更加规范。
接口如何定义?
* interface 接口名称{
* const 常量名=值 (标量)
* 抽象方法(没有方法体的方法)
* }
*
* 调用接口中的常量: 接口名::常量名;
接口如何使用?
* 接口要通过类去实现implements,要求 子类要实现接口中所有的抽象方法。
类与接口之间的关系?
* 一个类是可以同时实现多个接口的。