PHP-面向对象编程
1 面向对象(OO):
面向对象:
将要处理的问题抽象为对象,然后通过对象的属性和行为来解决对象的实际问题
三大特性:封装,继承,多态
面向过程和面向对象区别:
面向过程:最小单位是函数
面向对象:最小单位是对象
类:是具有相同属性和方法的集合,是一个独立的程序单位
对象:是类实例化之后的产物
类和对象的关系:
类的实例化结果就是对象,对象的抽象就是类
类就是一组具有(特征)成员属性和相同(相同)成员方法的对象
2 抽象一个类
类的声明
[权限修饰符] class 类名{
[public $property =[value...]]//属性
[function functionname(args)
//代码
]//类的方法
}
类名和变量名的明命名规则相似,如果有多个单词组成,习惯上每个单词的首字母大写,而且要有意义
成员属性:为静态描述,可以使用php中的标量类型和符合类型
格式: public 属性名称
也可以采用private 等,当不确定的用那个的时候,使用public或者var(php4)
权限修饰符号默认采用:public
成员方法:为动态描述
格式:
[权限修饰符] function 方法名(args){
//代码
}
3 实例化对象
创建对象:
$对象名称= new 类名称([参数]);
实例化多个对象,各对象之间都是独立的,存放在不同的内存空间
如果对象创建时,没有手动的设置构造方法,则系统自动创建一个不带参数的默认构造函数
对象类型在内存中的分配:
逻辑内存: 栈空间段 堆空间段 初始化数据段 代码段
栈空间段
特点是:先进先出
空间小,cpu访问速度快,存放程序中临时创建的变量,占用空间不大并且长度不变的,[整型,浮点型...]
堆空间段:
程序运行中,被动态分配的的内存段,大小不固定,存储诗句长度可变或占用内存较大的数据
[字符串,数组,对象]
初始化数据段:
存储可执行文件中已初始化的全局变量[程序静态分配的变量]
代码段:
可执行文件的操作指令,是可执行文件在内存中的镜像
对象类型在内存存储方式
例如:
class person{
public $name;
public $age;
public $sex;
function eat(){}
function run(){}
}
$person=new person();
等式右边为堆内存,存放对象实例
左边为棧内存,存放对象引用
1 当new person()的时候,计算机在堆内存就为我们创建的对象开辟一个新的空间,存储对象实例
|--$name;
|--$age;
new person() |--$sex;
|--eat();
|--run();
每个对象都有一个十六进制的内存地址,例如:0x001
2 对象中的eat(),run()方法的存放在可执行代码段中,堆内存中的每个都可以引用.
function eat(){}
function run(){}......
3 当创建的对象赋值给$person时,就将对象的十六进制地址存放在了棧内存,并形成一个指针指向堆内存的对象,
形成了一个对象的引用,通过对象的引用类访问对象
对象中成员的访问:
使用:"->"符号
对象引用名->成员属性/成员方法
例如:$person->name;
特殊的对象引用:$this
属于对象级别,创建了那个对象,$this就代表那个对象,在类的成员方法中使用,具体代表了实例化的对象操作
构造方法和析构方法
构造方法:
php4:名称必须和类名相同
php5:使用魔术方法关键词:__construct
Function __construct([参数]){}
触发时机:创建一个对象的时候自动调用执行
作用:可以在创建对象的实现对象初始化
析构方法:
Function __destruct(){}
触发时机:在销毁一个对象的时候自动调用执行(php5新特性)
作用:释放资源,关闭连接,做一些清理工作等
注:对象的引用存放在棧内存,其特点是先进先出,所以后创建的对象先销毁.
4 封装性
特点:
1 把对象的全部成员方法和成员方法结合在一起,形成一个不可分割的独立单位
2 信息屏蔽,尽可能的隐藏内部细节,对外形成一个边界只保留有限的对外接口
设置私有成员:
使用关键字"private"修饰
private的访问权限:
在类的外部不能够访问
在类的内部可以访问
子类中不可以访问
如果没有设置访问权限:默认为public
魔术方法:php中把两个(__)开头的类方法叫做魔术方法.
__consturct() / __destruct() / __call() / __set()
__get() / __clone() / __isset() / __unset() / __sleep() / __wakeup()
__set()
Function __set($proName,$proValue){
$this->$proName=$proValue;
}
触发时机:在类的外部设置类的私有属性成员值的时候自动调用
特点:1需要两个参数(属性的名称,设置的属性的值)
2可以在属性的方法前面加上private关键词修饰,在5.3以上版本中加上private修饰,会出现警告
__get()
Function __set($proName){
Return $proName;
}
触发时机:在类的外部获取类的私有属性成员的时候自动调用
特点:1 需要一个参数,就是获取私有成员属性的属性名
__isset()
Function __isset($proName){
Isset($proName);
}
触发时机:在类的外面isset()或者empty()检测类的私有成员属性是否设置时自动调用
特点: 1 需要一个参数,检测私有属性的属性名
__unset()
Function __unset($proName){
Isset($proName);
}
触发时机:在类的外面unset()有成员属性的时候自动调用
特点:1 需要一个参数,删除私有属性的属性名
5 继承性
特点:
1 使所建立的软件具有开放性,可扩充性
2 增加了代码的可重用性,简化了类和对象创建的工作量
3 增加类软件的可维护性,通过继承,使公用的特性得到共享,扩展和延伸
4 php中继承为单继承,用子类扩展父类
类继承的应用
1 声明一个子类,使用extends关键字去继承扩展一个父类
2 子类可以继承父类的所有内容,包括成员属性,成员方法,构造方法
3 可以在子类中使用"$this->"来调用继承父类过来的内容
对类成员的访问控制
Public:公用的
类内部:可以访问
类外部:可以访问
子类中:可以访问
Protected:受保护的
类内部:可以访问
类外部:不可以访问
子类中:可以访问
Private:私有的
类内部:可以访问
类外部:不可以访问
子类中:不可以访问
子类中重载父类的方法
1 子类可以声明和父类相同的方法名,即子类覆盖了父类中同名的方法
2 子类中调用父类中方法
对象->成员方法名:子类调用父类继承过来的方法
parent::成员方法名:子类调用覆盖的父类方法
3 子类中编写构造方法,如果父类中也有构造方法一定要去调用一次父类中被覆盖的构造方法
4 父类和子类都存在构造方法,系统会调用子类的方法
5 子类重载父类的方法,则方法的权限等级不能低于父类(子类可以访大权限,但不能缩小权限)
6 常见的关键字和魔术方法
final关键字:
Final class Demo{
Final function add();
Final function del();
}
1 final不能修饰成员属性
2 final只能修饰类和方法
作用:
1 使用final修饰的类,不能被继承
2 使用final修饰的方法不能被子类重载覆盖
static关键字:
Class Demo{
Static const USER;
Static function fun1(){}
}
1 static只能修饰成员属性和成员方法,不可以修饰类
2 用static修饰的成员属性,可以被同一个类所以对象共享,属于类级别
3 静态的数据存在内存中的静态数据段里,节约资源,提高效率
4 静态的数据在类第一次加载时分配到内存里,以后用到类时则直接调用
第一次加载:指的是第一次使用时例如$person->say(),Person::say()...
5 访问类中static修饰的成员属性和成员方法,类不需要声明,不需要创建对象
6 静态成员属性不能通过$this去访问
7 static和private等权限修饰关键字可以同时存在,效果叠加
8 静态方法中不能包含非静态的成员,在非静态的方法中可以包含静态成员
9 在静态成员方法中不能出现$this关键字 ,但是可以在静态成员方法内部使用$this调用静态成员方法
10 静态成员方法的访问
访问方式:
在类中:
类名::成员方法
self::成员方法(self为类级别)
类外部:
类名::类中成员
对象名称->成员方法
11 静态数据的访问速度较快,所以在不影响结构的情况下,尽量将成员属性和对象设置为静态的
Const
Class Demo{
Static const USER;
Static function fun1(){}
}
1 只能修饰成员属性
2 类中声明成员属性常量使用const关键字
3 常量通常使用大写(命名方式和define是一样的)
4 常量只能是标量,前面没有$符号
5 常量一定要在声明时给初值,在程序运行的过程中常量的值是不可以改变的
6 常量的访问方式,不能用$this->访问:
7 常量的访问:
在类中:
类名::常量
self:常量
类外部:
类名::常量(不需要实例化)
__clone()
1 当对象赋值给另一个对象的时候,则为引用关系
$p=new Person();
$p1=$p;
2 对象克隆(clone Oject)的时候,用clone关键字
当$p1=clone $p;时
Function __clone(){
//$this:代表克隆的对象,可以进行初始化操作
}
注:
对象的引用,为一个对象多个名称,内存中指针指向同一个地址
对象的克隆,复制一个新的对象,相当于创建了一个新的对象
触发时机:在克隆对象的时候自动调用
作用:在克隆的复本对象中进行初始化设置,在__clone()方法中$this表示复本对象
特点:不需要参数
复本的对象$this,该方法类似__construct()
__toString()
Function __toString(){
Return "需要输出的字符串";
}
触发时机:当echo一个对象的时候,系统自动调用__toString()方法
特点:该方法必须return一个字符串
__call()
Function __call($proName,$proValue){
//$proName:指的是调用的方法名
//$proValue:指的是有参数组成的数组
}
触发时机:当调用一个不存在的方法时,系统自动调用
作用:处理不存在方法的错误调用
特点:__call()需要两个参数,第一个调用的方法名,第二个为参数组成的数组
__autoload()
Function __autoload($className){
Include $className.'.class.php';
}
注意:该魔术方法是唯一一个不再类中的方法
触发时机:只要在页面中使用到类的时候该方法自动执行,去寻找该类
并将该类的类名自动传递给__autoload()方法的参数
特点:只用一个参数,当使用那个类的时候,该方法自动执行寻找相应的类,并将类名赋值给参数
作用:自动加载所需的类
使用到类例如:
$p->say();
Person::test();...
对象串行化
1 串行化就是把整个对象转化为二进制字符串
2 串行化应用:
1 对象需要在网络中传输时,将对象串行化成二进制串后在网络中传输
2 对象需要持久保存时,将对象串行化之后写入文件或数据库
3 串行化方法:
串行化:serialize()参数是一个对象,返回串行化后的二进制串
反串行化:unserialize()参数是对象的二进制串,返回新生成的对象
__sleep()
$p=new Person('张三',23,'女');
$str=serialize($p);
File_put_contents('mess.txt',$str);
Function __sleep(){
Return array();//array中输入需要进行序列化的成员
}
触发时机:在序列化时自动调用
作用:将一个对象的部分成员属性或者功能进行串行化
只要这个方法返回一个数组,数组中的值为对象成员要序列化的名称
如果不使用这个方法,则整个对象进行序列化
__wakeup()
$p=unseralize(file_get_contents('mess.txt'));
Function __wakeup(){
//$this代表序列化的对象
}
触发时机:在对象反序列化的时候自动调用执行
作用:对反序列化后的对象进行初始化工作
类似此类的方法有:__construct(初始化参数),__clone(不需要参数),__wakeup()
7 抽象类和接口
注:抽象类是一种特殊的类,接口是一种特殊的抽象类
抽象类:
抽象方法:没有方法体的方法就是抽象方法,例如 function test();
抽象类:含有抽象方法的类就是抽象类
1 抽象方法必须用abstract修饰
2 如果一个类含有抽象方法,这个类就是抽象类,必须用abstract修饰
3 抽象类中可以有非抽象方法,在抽象类中可以包含多个抽象方法
4 抽象类可以声明属性和常量
5 抽象方法关键字和权限修饰关键字可以同时存在private abstract function test();效果叠加
6 抽象类不能够被实例化,不能够创建抽象类的对象
7 抽象类必须只能通过继承来实现
8 继承抽象类的子类必须实现抽象类的所有方法
9 子类实现抽象方法时,抽象方法的参数和默认值必须保持一致
10 抽象方法之间是可以继承的,必须按照规范来实现功能
接口技术
1 接口中所有方法均为抽象方法
2 不能在接口中声明变量,只能用const修饰的常量
3 接口中的所有成员必须都是public权限等级
4 接口的声明不能用abstract修饰,而是用interface关键字
5 实现接口不能用extends,而是用implements关键字
6 在实现接口的子类中,接口的所有方法都要实现,方法的形参,默认值都需要保持一致
7 子类可以实现多个接口,各个接口使用逗号隔开
implements interfaceName1,interfaceName2.....{}
8 子类在实现接口的同时还可以继承抽象类和普通类,
9 抽象类客普通类的实现使用implments关键字,而接口实现接口使用关键字extends
10 接口不能被实例化,需要子类去实现
11 接口中不能声明变量,只能声明常量
抽象类和接口的比较:
1 作用相同,不能创建对象,都需要子类去实现
2 接口的声明和抽象类不一样,接口interface,抽象列abstract
3 使用一个类实现接口,用implements,不用extends,抽象类用extends
4 接口中所有的成员方法必须都是抽象方法,不用abstract修饰
5 接口中的成员属性只能声明常量,不能声明变量,
6 接口类的访问权限必须是public,抽象列最低可以是protected
8 多态性
多态
php中的多态性指的是方法重写,指的是一个子类可以重新修改父类中的方法,使其具有自己的特征
多态可以通过声明抽象类和接口来实现