|
--对象的3大特性:封装,继承,多态。
--对象概述
从概念上讲什么是对象?对象就是一个东西,一个实体。
php语言(大多面向对象程序语言)如何描述对象?借助成员属性、成员方法描述。
成员属性描述对象的外观和状态;
成员方法描述对象的功能。
--类与对象的关系
声明类-->实例化对象(创建对象)-->使用对象
--类的声明
[修饰类的关键字]> {
[private public protect var const static...] 变量名 //成员属性的前面必须加修饰词,如果不确定用什么修饰词,就用var
function 函数名
{ 函数体 } //成员方法
}
--保存类的文件
通常一个文件只保存一个类,文件名中包含类名,比如:类名.class.php(这样见到文件名就知道保存的是类,也知道是什么类;另一方面,这样命名php才能够实现自动加载)
--关于成员属性
- 成员属性的前面必须加修饰词,如果不确定用什么修饰词,就用var.
- 成员属性如果在不同实例化中可能取不同的值,不要给初始值。
--对象的创建
- 格式:$对象名 = new 类名;
- 每创建一个对象,就在内存中分配一份空间。
--对象的存储
php语言中,字符串、数组、对象都是存储在堆(另外几种存储空间是:数据段,代码段,栈)中的。
对象自身存储在堆中,对象变量(存储对象的地址,可以理解为c++中的指向对象的指针)存储在栈中。
--php中的this指针
php的成员方法中如果使用成员属性或者其他成员方法,需要手工写上$this(c++里不用写,默认是本对象,参见http://stark.blog.运维网.com/189176/696281)
--php构造方法
- 含义:php对象创建以后,第一个自动调用的方法。用来初始化对象(注意:是先创建了对象,才调用的方法)
- php4中,构造方法名与类名相同。
- php5中,构造方法选择使用魔术方法__construct(),所有类的构造方法都用这个名。使用这个名字的好处:修改类名称时,构造方法不用改名。
- 为了版本兼容,这两个方法可以都写在一个类中,php5优先使用__construct()。
--php析构方法
- 方法名:__destruct()
- 含义:对象被释放前,最后一个自动调用的方法。用来关闭一些资源,做一些清理工作。
- 对象的释放时机:php(java)使用垃圾回收器自动释放垃圾对象(函数返回时,函数中声明的对象就是垃圾对象了)。c++中手动释放不用的对象(用delete函数)。
- 手工释放方式:php中也可以手工释放对象。$对象名=null;
--魔术方法
- 含义:系统提供的一些方法(方法名系统给的),这些方法是系统自动调用的,且有特定的调用时机(比如__construct()在对象创建时调用)。
- 使用方法:在类中写上这个方法,就可以使用。
- 特点:都以__(两个下划线)开头。
- 特权:魔术方法比较特殊,不受权限的限制,可以访问private成员以及protect成员。
- 例子:
- 用在类中的魔术函数
- __construct() //构造函数
- __desctuct() //析构函数
- __set() //用"对象->属性 = 值"直接设置私有成员属性时,自动调用的方法
- __get() //用"对象->属性"直接读取私有成员属性时,自动调用的方法
- __isset() //直接用isset()查看对象的私有属性是否存在时,自动调用的方法
- __unset() //直接用unset()删除对象的私有属性时,自动调用的方法
- __clone()
- __call() //调用不存在的成员方法时,自动调用此方法,用于处理异常
- __sleep() //对象串行化时,自动调用的方法,用于决定串行化哪些成员属性
- __weakup() //对象反串行化时,自动调用的方法,用于决定对成员属性进行哪些改动。
- __toString() //用echo 输出对象时,自动调用,用于快速获取对象的字符串表现形式
- 其他魔术函数
- __autoload() //用于自动包含类的定义文件,只要用到类名,就会自动调用这个函数
--封装性(面向对象的3大特性之一)
- 含义:把对象的成员(方法成员,属性成员)结合成独立的单位,并尽可能隐藏对象的内部细节。
- 关键字:public private protect
- 封装的作用:
- 对于方法:隐藏类实现的内部细节,类里面可能定义了100个方法,只有5个方法是需要对外的,另外95个都是为这5个服务的,所以把这95个隐藏起来是比较好的。仅开放必要的接口,也有利于别人了解该类。
- 对于属性:避免了被外部修改为非法数据的危险。对于需要外部修改的属性,可以通过public方法来设置(经过方法改值或取值是可控的)。
__get($proName)
- 含义:用"对象->属性"直接读取私有(公有也用不着调用这个函数了)成员属性时,自动调用的方法
- 参数:__get($proName)方法里有1个参数,就是需要返回属性的属性名(参数值是系统自动传入的)。
__set($proName,$proValue)
- 含义:用"对象->属性 = 值",直接设置私有(公有也用不着调用这个函数了)成员属性时,自动调用的方法
- 参数:__set($proName,$proValue)方法里有2个参数,就是需要设置属性的属性名、属性值(参数值是系统自动传入的)。
__isset($proName)
- 含义:直接用isset()查看对象的私有属性是否存在时,自动调用的方法。
- 参数:__isset($proName)里面有1个参数,传递需要查询的属性名。返回值应该为bool型。
__unset($proName)
- 含义:直接用unset()删除对象的私有属性时,自动调用的方法。
- 参数:__unset($proName)里面有1个参数,传递需要删除的属性名。
--继承性(面向对象的3大特性之一)
- 作用:提高代码的可重用性(子类不用再写一遍父类的属性),可维护性(如果需要修改公共属性,修改父类就可以影响到所有子类)
- 和C++的区别:C++是多继承的面向对象语言(同一个类可以有多个父类);PHP、Java是单继承(一个类只能有一个父类)
- 声明方法:使用关键字extends去继承(扩展)一个父类。例如
- class student extends person
- {}
子类可以继承父类的所有成员(对于private成员,子类是不能访问的)。
注意:子类中重载的方法,不能低于父类中的访问权限。(子类可以放大权限,不能缩小权限)
--类的权限
private
protected
public
自己类中
Y
Y
Y
子类中
N
Y
Y
类外部
N
N
Y --成员方法重载
- c++的重载:父类与子类的函数名相同,参数个数或参数类型不同。
- php的重载:只要子类和父类的方法名相同,子类的方法就覆盖父类的方法,实现重载。因为php函数的参数个数是可以任意加的,并且是弱类型的,所以按c++的重载方式显然不行。
- 重载如果用于对父类方法的扩展,需要在子类方法中调用父类中被覆盖掉方法。
- 对于子类的构造方法,如果父类中也有构造方法,一定要在子类中调用父类的构造方法。
--子类方法中调用父类中被覆盖掉的方法
在子类中写:父类名::方法名,或者是parent::方法名
--php中常用的关键字:final,static,const
--final关键字
- 使用方法:用来修饰类、成员方法。不能修饰成员属性。
- 作用:
- 使用final修饰的类不能被子类继承。
- 使用final修饰的方法,不能被子类方法覆盖(重载)。
--static关键字
- static可以修饰成员属性、成员方法。不能修饰类。
- 作用:
- 用static修饰的成员属性,可以被类中的所有对象共享。
- 用static修饰的成员方法,可以不用创建对象就使用方法。
- 存储位置:静态成员属性存储在数据段中的。
- 何时被加载:在类第一次被加载时,静态成员属性被分配到内存数据段中,以后再用到类,就从数据段中读取.
- 什么是类被加载:只要在程序中使用这个类(类名出现就可以,不一定要创建对象)
- 注意:静态成员(属性与方法)都要使用类名去访问,不用创建对象,不用对象去访问。
- 使用方法(静态成员属性与静态成员方法):
- 如果在类中使用静态成员,可以使用 类名::静态成员。
- 如果在类中使用静态成员,可以使用 self代表本类,self::成员名
--静态成员方法的注意事项:
- 禁忌:静态方法中,不能访问非静态成员(包括非静态的属性与方法)。因为非静态成员需要对象来访问,而静态方法与对象无关,所以它也就不能访问非静态成员。
- 什么时候用:如果一个方法能确保不访问非静态成员,可以把这个方法声明为静态方法(好处是不用创建对象,就能使用这个方法)。
- 应用举例:单态设计模式中,用静态方法创建对象。
--const关键字
- 用途:修饰类的成员属性为常量。
- 命名方式及取值范围:与define一样(名字全大写,在声明和使用时都不需要$符号。;取值为标量)
- 访问方式:和static成员属性是一样(在类外部,使用 类名::常量名;在类内部,使用 self::常量名)。
- 存储位置:和static成员属性一样,在数据段中。
- 注意:
- 只能用于修饰成员属性,不能用在类外(类外定义常量用define)。
- 要在声明时就给初值。
- 举例:
- class demo
- {
- const HOST = "localhost";
- }
--__call($methodName,$args)魔术方法
- 作用:调用不存在的方法时,系统会报错,然后程序推出。__call($methodName,$args)魔术方法用于解决此情况。
- 什么时候调用:会在调用一个不存在的成员方法时调用。
- 参数:$methodName 不存在方法的方法名;$args不存在方法的参数组成的数组。
__toString()魔术方法
- 作用:用echo 输出对象时,自动调用,用于快速获取对象的字符串表现形式。
- 什么时候调用:用echo直接输出对象时,自动调用。
- 参数:无。
- 返回值:字符串,要构建能够表现对象内容的字符串。
--clone关键字
- 为什么会有这个关键字:如果直接对象间赋值,比如$p1 = $p2的话,只是把$p2的指针赋值给了$p1,这两个引用还是指向了同一个对象。所以诞生了clone关键字,它指示系统创建一个新对象,并浅拷贝原来对象的属性。
- 作用:创建一个对象,并浅拷贝原来对象的值(当一个对象被克隆时,PHP5将执行一个所有对象的属性的浅拷贝。任何对其它对象引用的属性将只保留引用。)。如果想实现深度拷贝,需要用到__clone()方法。
- 使用方法:$p1 = clone $p2;
__clone()魔术方法
作用:使用clone关键字时自动调用此函数。可用于克隆对象时做特殊的操作(比如clone电视机对象,但又不想复制电视机编号,就用__clone()方法做特殊处理)。
详细说明见:http://stark.blog.运维网.com/189176/699583
__autoload()
- 位置:魔术方法中唯一一个不在类中添加的方法,其他魔术方法都是作为类的成员方法。
- 作用:当工程中类的定义文件比较多,包含起来很麻烦时,可以使用此方法,用于自动包含类的定义文件。
- 什么时候调用:只要用到类名,就会自动调用这个函数。
- 什么叫做用到类名:
- new一个对象,比如$p1 = new point;
- 用类名引用方法,point::staMethod;
- 典型案例:
- function __autoload($className)
- {
- /**
- *include前面一般都有判断,比如判断className字符串的后面6个字符是什么就到相应的目录去找文件
- */
- include "./".$className."class.php"; //为了能使用这个函数,类的定义文件一般都定义为 类名.class.php
- }
由于linux系统区分文件名大小写,所以用strtolower($className) 将类名都转为小写。include "./".strtolower($className)."class.php";
--对象串行化(序列化):将一个对象转换为二进制串。(对象是存储在内存中的,把它转换为二进制串就可以保存起来)
- 作用:
- 可以将对象长时间存储在数据库或文件中。
- 对象在多个php文件中传输时,也需要用到。
- 使用的函数:
- serialize()参数是一个对象,返回的是一个串行化的二进制串。//然后可以将二进制串存到文件中
- unserialize()参数是一个二进制串,返回的是一个新生成的对象。//需要提前从文件中读取二进制串。
__sleep() 魔术方法
- 什么时候调用:对象串行化时,自动调用的方法,用于决定串行化哪些成员属性。
- 作用:将一个对象部分串行化。
- 使用方法:只要这个方法中返回一个数组,数组中有几个元素(元素值就是成员属性名)就串行化几个成员属性。如果不加这个方法,则串行化所有成员属性。
__wakeup
作用:对象反串行化时,自动调用的方法,用于决定对成员属性进行哪些改动。
--会创建新对象的情况
- new //会调用__construct()
- 使用clone关键字赋值 //会调用__clone()
- unserialize() //会调用weakup()
--抽象方法
- 定义:如果一个类中的方法没有方法体(就是一个方法没有使用{},而直接使用分号结束),并且使用abstract关键字去修饰,就是抽象方法。
- 例如:abstract function test(); //没有方法体,抽象方法
function test() {} //有方法体,只是方法体为空
--抽象类
- 定义:如果一个类中有一个方法是抽象的,并且它本身不能实例化对象,它的子类可以创建,但子类必须重载父类的抽象方法,那么这个类就是抽象类。
- 举例:抽象类必须使用abstract去修饰。abstract>
- 注意:
- 抽象类虽然是一种特殊的类,但它里面的其他成员与普通类一样(比如可以声明非抽象方法,成员属性)。
- 抽象类不能实例化(不能通过抽象类去创建一个对象)。
- 使用方法:
要想使用抽象类,必须要一个类去继承抽象类,而且要想使用这个子类(用子类创建对象),子类就不能再是抽象类,子类必须重写父类的抽象方法(给抽象方法加上方法体)。
- 作用:就是定义一些规范(抽象方法),让子类按照规范去实现自己的功能。
- 设计抽象类的目的:就是要将你自己写的程序,加入到别人已写好的程序中去。(别人不必等你开发完小模块后再开发后面部分,他只需告诉你他都需要哪些方法)
--接口技术
- 定义:接口是一种特殊的抽象类。
- 作用:接口的作用和抽象类相同,都是为了提供规范。
- 设计接口的目的:为了多继承(虽然php里不这么说,但实际作用就是多继承)。php是单继承语言,那么用抽象类就只能在子类实现父类的抽象方法,如果想要同时实现多个类的抽象方法,就引出了接口。
- 接口和抽象类的异:
- 声明方式不同:声明接口用 interface 接口名{}
- 成员方法不同:接口的所有方法必须都是抽象方法。(抽象类可以有普通方法)因为都是抽象方法,接口方法不用abstract修饰。
- 成员属性不同:接口的所有属性必须都是常量。(抽象类可以有变量成员属性)
- 接口中成员访问权限,必须都是public.(抽象类可以有protect成员)
- 使用类去实现接口,不是extends,而是implements。
- 实现接口时,不能再添加成员。(继承抽象类时,可以添加成员)
- 一个类可以去实现多个接口。(一个类只能继承一个抽象类)
- 接口和抽象类的同:都是为了提供规范,都自身不能实例化,需要子类去继承(对接口来说是实现)后再实例化。
- 接口的使用方法:
- 可以使用抽象类去实现接口的部分方法(当然抽象类还需要普通类去继承):
- abstract demo implements test
- {
- fun1(){} //test接口还有fun2,在抽象类demo中没有实现
- }
还可以使用普通类去实现接口的全部方法:
- class demo implements test
- {
- fun1(){}
- fun2(){}
- }
可以使用接口去继承接口:
- interface domo extends test
- {
- fun3(){} //继承的接口,可以添加成员
- fun4(){} //继承的接口,可以添加成员
- }
可以同时实现多个接口,用逗号分隔多个接口名称:
- interface Demo
- {
- const HOST="localhost";
- const USER="Admin";
- function fun1();
- function fun2();
- }
- interface Demo2 extends Demo
- {
- function fun3();
- function fun4();
- }
- interface Demo3
- {
- function fun5();
- function fun6();
- }
- interface Demo4
- {
- function fun7();
- }
- class Test implements Demo2,Demo3,Demo4
- {
- function fun1(){
- }
- function fun2(){
- }
- function fun3(){
- }
- function fun4(){
- }
- function fun5(){
- }
- function fun6(){
- }
- function fun7(){
- }
- }//同时实现了:Demo,Demo2,Demo3,Demo4几个接口
可以在继承一个类的同时,实现一个或多个接口:(先继承,再实现)
- interface Demo {
- const HOST="localhost";
- const USER="Admin";
- function fun1();
- function fun2();
- }
- interface Demo2 extends Demo {
- function fun3();
- function fun4();
- }
- interface Demo3 {
- function fun5();
- function fun6();
- }
- interface Demo4{
- function fun7();
- }
- class Hello {
- function fun8(){
- }
- }
- class Test extends Hello implements Demo2,Demo3,Demo4 {
- function fun1(){
- }
- function fun2(){
- }
- function fun3(){
- }
- function fun4(){
- }
- function fun5(){
- }
- function fun6(){
- }
- function fun7(){
- }
- }
--多态性(面向对象的3大特性之一)
含义:“多态”是面向对象设计的重要特性,它展现了动态绑定(dynamic binding)的功能,也称为“同名异式”(Polymorphism)。
多态的功能可让软件在开发和维护时,达到充分的延伸性(extension)。事实上,多态最直接的定义就是让具有继承关系的不同类对象,可以对相同名称的成员函数调用,产生不同的反应效果。
--php代码和前台html混合
目前所学的都是两种代码混合,使用mvc模式和模板技术后可以将两种代码分离,将逻辑层和表现层分离出来。
--调用本类
方法中可以使用常量"__CLASS__",表示本类的类名。
--关于使用某个类的方法作为回调函数
参数需要使用数组,数组有2个成员:array(类名,回调函数名), 例如:
- session_set_save_handler(array("类名","方法名")); //函数session_set_save_handler()
- 使用某类的方法作为回调函数。
|
|
|