1. 云栖社区>
  2. PHP教程>
  3. 正文

php学习_第8章_PHP面向对象的程序设计

作者:用户 来源:互联网 时间:2017-12-01 14:18:42

php对象学习程序设计面向

php学习_第8章_PHP面向对象的程序设计 - 摘要: 本文讲的是php学习_第8章_PHP面向对象的程序设计, --对象的3大特性:封装,继承,多态。 --对象概述 从概念上讲什么是对象。对象就是一个东西,一个实体。 php语言(大多面向对象程序语言)如何描述对象。借助成员属性、成员方法描述。 成员属性描述对象的外观和状态; 成员方法描述对象的功能


--对象的3大特性:封装,继承,多态。



--对象概述


从概念上讲什么是对象。对象就是一个东西,一个实体。


php语言(大多面向对象程序语言)如何描述对象。借助成员属性、成员方法描述。


成员属性描述对象的外观和状态;


成员方法描述对象的功能。



--类与对象的关系


声明类-->实例化对象(创建对象)-->使用对象



--类的声明


[修饰类的关键字] class 类名


{


[private public protect var const static...] 变量名 //成员属性的前面必须加修饰词,如果不确定用什么修饰词,就用var


function 函数名


{ 函数体 } //成员方法


}



--保存类的文件


通常一个文件只保存一个类,文件名中包含类名,比如:类名.class.php(这样见到文件名就知道保存的是类,也知道是什么类;另一方面,这样命名php才能够实现自动加载)



--关于成员属性



成员属性的前面必须加修饰词,如果不确定用什么修饰词,就用var.
成员属性如果在不同实例化中可能取不同的值,不要给初始值。


--对象的创建



格式:$对象名 = new 类名;
每创建一个对象,就在内存中分配一份空间。


--对象的存储


php语言中,字符串、数组、对象都是存储在堆(另外几种存储空间是:数据段,代码段,栈)中的。


对象自身存储在堆中,对象变量(存储对象的地址,可以理解为c++中的指向对象的指针)存储在栈中。



--php中的this指针


php的成员方法中如果使用成员属性或者其他成员方法,需要手工写上$this(c++里不用写,默认是本对象,参见http://stark.blog.51cto.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去继承(扩展)一个父类。例如
classstudentextendsperson{}
子类可以继承父类的所有成员(对于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)。
要在声明时就给初值。


举例:

classdemo{constHOST="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.51cto.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 class demo{ abstract function test();}
注意:

抽象类虽然是一种特殊的类,但它里面的其他成员与普通类一样(比如可以声明非抽象方法,成员属性)。
抽象类不能实例化(不能通过抽象类去创建一个对象)。


使用方法:

要想使用抽象类,必须要一个类去继承抽象类,而且要想使用这个子类(用子类创建对象),子类就不能再是抽象类,子类必须重写父类的抽象方法(给抽象方法加上方法体)。



作用:就是定义一些规范(抽象方法),让子类按照规范去实现自己的功能。
设计抽象类的目的:就是要将你自己写的程序,加入到别人已写好的程序中去。(别人不必等你开发完小模块后再开发后面部分,他只需告诉你他都需要哪些方法)


--接口技术



定义:接口是一种特殊的抽象类。
作用:接口的作用和抽象类相同,都是为了提供规范。
设计接口的目的:为了多继承(虽然php里不这么说,但实际作用就是多继承)。php是单继承语言,那么用抽象类就只能在子类实现父类的抽象方法,如果想要同时实现多个类的抽象方法,就引出了接口。
接口和抽象类的异:

声明方式不同:声明接口用 interface 接口名{}
成员方法不同:接口的所有方法必须都是抽象方法。(抽象类可以有普通方法)因为都是抽象方法,接口方法不用abstract修饰。
成员属性不同:接口的所有属性必须都是常量。(抽象类可以有变量成员属性)
接口中成员访问权限,必须都是public.(抽象类可以有protect成员)
使用类去实现接口,不是extends,而是implements。
实现接口时,不能再添加成员。(继承抽象类时,可以添加成员)
一个类可以去实现多个接口。(一个类只能继承一个抽象类)


接口和抽象类的同:都是为了提供规范,都自身不能实例化,需要子类去继承(对接口来说是实现)后再实例化。
接口的使用方法:

可以使用抽象类去实现接口的部分方法(当然抽象类还需要普通类去继承):



abstractdemoimplementstest{fun1(){}//test接口还有fun2,在抽象类demo中没有实现}
还可以使用普通类去实现接口的全部方法:
classdemoimplementstest{fun1(){}fun2(){}}

可以使用接口去继承接口:


interfacedomoextendstest{fun3(){}//继承的接口,可以添加成员fun4(){}//继承的接口,可以添加成员}

可以同时实现多个接口,用逗号分隔多个接口名称:


interfaceDemo{constHOST="localhost";constUSER="Admin";functionfun1();functionfun2();}interfaceDemo2extendsDemo{functionfun3();functionfun4();}interfaceDemo3{functionfun5();functionfun6();}interfaceDemo4{functionfun7();}classTestimplementsDemo2,Demo3,Demo4{functionfun1(){}functionfun2(){}functionfun3(){}functionfun4(){}functionfun5(){}functionfun6(){}functionfun7(){}}//同时实现了:Demo,Demo2,Demo3,Demo4几个接口

可以在继承一个类的同时,实现一个或多个接口:(先继承,再实现)


interfaceDemo{constHOST="localhost";constUSER="Admin";functionfun1();functionfun2();}interfaceDemo2extendsDemo{functionfun3();functionfun4();}interfaceDemo3{functionfun5();functionfun6();}interfaceDemo4{functionfun7();}classHello{functionfun8(){}}classTestextendsHelloimplementsDemo2,Demo3,Demo4{functionfun1(){}functionfun2(){}functionfun3(){}functionfun4(){}functionfun5(){}functionfun6(){}functionfun7(){}}

--多态性(面向对象的3大特性之一)


含义:“多态”是面向对象设计的重要特性,它展现了动态绑定(dynamic binding)的功能,也称为“同名异式”(Polymorphism)。


多态的功能可让软件在开发和维护时,达到充分的延伸性(extension)。事实上,多态最直接的定义就是让具有继承关系的不同类对象,可以对相同名称的成员函数调用,产生不同的反应效果。



--php代码和前台html混合


目前所学的都是两种代码混合,使用mvc模式和模板技术后可以将两种代码分离,将逻辑层和表现层分离出来。



--调用本类


方法中可以使用常量"__CLASS__",表示本类的类名。



--关于使用某个类的方法作为回调函数


参数需要使用数组,数组有2个成员:array(类名,回调函数名),例如:


session_set_save_handler(array("类名","方法名"));//函数session_set_save_handler()使用某类的方法作为回调函数。



以上是云栖社区小编为您精心准备的的内容,在云栖社区的博客、问答、公众号、人物、课程等栏目也有的相关内容,欢迎继续使用右上角搜索按钮进行搜索php , 对象 , 学习 , 程序设计 面向 ,以便于您获取更多的相关知识。