php class类的用法详细总结
一:结构和调用(实例化):class className{} ,调用:$obj = new className();当类有构造函数时,还应传入参数。如$obj = new className($v,$v2…); 二:构造函数和析构函数:1、构造函数用于初始化:使用__construct(),可带参数。 2、但析构函数不能带参数(用于在销去一个类之前执行一些操作或功能)。析构函数用__destruct()做名称。在脚本执行结束时,会销掉内存中的对象,因此可不用析造函数,但有些比如COOKIE等,就应当要用此函数销掉。 知识点:在PHP4中也提供了构造函数,但使用的是与类同名的类方法,在PHP5仍能兼容这种做法,当一个类中没有包含__construct时,会查找与类同名的方法,如果找到,就认为是构造函数,如下: 类的主家庭成员:属性、方法、常量、静态成员 三、类的属性:有两种方法对类的属性赋值或取值。1、使用公共作用域public关键词。 2、使用__set()和__get()来分别赋值和取值,前者称为设置方法(setter)或修改方法(mutator),后者称为访问方法(accessor)或获取方法(getter)。建议使用这种方法:优点: A、可在__set()统一进行数据验证。 B、便于统一管理属性。 注意: 第一:__set()和__get()只对私有属性起作用,对于用public定义的属性,它们两个都懒理搭理,如下: 第二:__set($n,$v)要带两个参数。而__get($n)只能有一个参数。实例: 四、类的方法:理解成类当中的函数即可。
调用: 1、内部调用:可使用$this->Fanname();或$this->addab()或test::addab(); 2、实例化调用时,用$e->addab();即可。对于在该方法中没有使用$this关键字的,如上例中的: 五、类的常量:如果类的属性理解成类中的变量,那么类的常量和变量是不一样的,其定义方法为:代码如下:class test{ private $a; const PI = '3.14′; ….. //在类中调用上面的常量用两种方法,“$this::PI”,或 “类名::PI”,这里就是test::PI,如下: function getvalue(){ return $this->a * $this::PI; //或$this->a * test::PI,用this关键字或类名均可,但都要用双冒号。 } } $e= new test(); $e->PI =5; //注意,这里用 ->只是创造了一个也是名为PI的属性,而不是改变类中的PI常量的值。 echo $e::PI; //这个才是调用类的常量。 常量只能用双冒号::来调用。并且不能更改其值。 在类外部实例化后调用类常量同样也有两种方法。方法为: “$e::PI” 或 “test::PI”,共同点是都要用冒号,不同点是外部不能用this关键字,只能用实例名,但类名::PI是通用的。 六、类的静态成员(静态属性或静态方法):如果需要创建供所有类的实例共享的字段或方法。就得用静态成员。有两个特征: 1、静态成员是共产主义者,它让脚本上的所有该类的实例调用,但不能借助类的特定实例名调用,而是在类的外部,统一使用“类名::$成员名”的方式调用。而类的内部则统一使用 “self::$成员名”来调用。 2、当每一次新创建实例时,静态成员会从上次创建的实例最后值开始重新计算,而不是类中初始的值开始计算。 3、对于用public定义的静态成员,可以在外部更改它的值。private等则不行。 七、关键字:(一)this关键字:用于类的内部指代类的本身。来访问属性或方法或常量,如$this->属性名或方法名。$this::常量名。this还可以用在该类的子类中,来指代本身的属性或方法。
(二)双冒号“::”关键字:用于调用常量、静态成员。 (三)self关键字:在类的内部与双冒号配合调用静态成员,如 self::$staticVar.,在类的内部,不能用$this来调用静态成员。 (四)__toString():在类中使用__toString(),用于将类转成字串并打印类,用处不大:如: (六)__call():方法重载,参下面示例: 这是数字!';} function displayArr() { echo ‘ 这是数组!';} function displayOther() { echo ‘ 不是数组也不是数字!';} } $x='a'; (七)extends:继承: 如class a{} class b extends a{} 类b继承了类a 附:记忆:以后统一在调用方法或属性时用 “-> “,调用常量则用双冒号“::”,不会搞晕。 八、方法和属性的作用域:共有6种:public(默认,可省略,也等同于php6的var声明),private(私有,也不能由子类使用),protected(私有,但可由子类使用) ,abstract(抽象,参下文),final(阻止在子类中覆盖—也称重载,阻止被继承,用于修饰类名及方法,如final class test{ final function fun(){}} ,但不能用于属性),static(静态) 九:抽象类和抽象方法(abstract——注意:没有所谓抽象属性):抽象可以理解成父类为子类定义了一个模板或基类。作用域abstract只在父类中声明,但在子类中实现。注意事项: 1、抽象类不能被实例化,只能被子类(具体类)继承后实现。 2、抽象类必须在其子类中实现该抽象类的所有抽象方法。否则会出错。 3、在抽象方法中,只是声明,但不能具体实现:如abstract function gettow(){ return $this->p; }是错的,只能声明这个方法:abstract function gettow();(连方括号{}都不要出现),抽象方法和抽象类主要用于复杂的类层次关系中。该层次关系需要确保每一个子类都包含并重载了某些特定的方法。这也可以通过接口实现 4、属性不能被命名为抽象属性,如abstract $p = 5是错的。 5、只有声明为抽象的类可以声明抽象方法,但如果方法声明为抽象,就不能具体实现。如: 6、抽象类中,如果要实现具体的方法,不能声明为抽象。这样可能实际意义更大。可以把几个类库中共同的部分提取到抽象类中,其它的类继承抽象类即可。如下: 平均税率是 %d%%。',$this::TAX*100);} } $s = new BallShop; $s->open(); //你卖了ID为 :2314的商品 $shop->getTax(); 十:类型提示:注意,类型提示功能只能用于参数为对象的提示,而无法用于为整数,字串,浮点等类型提示。有些类的方法需要传入的参数为所期望的对象类型,可以用下面的方法达到强制实施此替则。要达到类型提示,只要在方法的对象型参数前加一个已存在的类的名称,如:function funname(OtherClassName $otherclassINSName,$c….),注意,OtherClassName必须是存在的类。如下:代码如下:class em{ var $k=56; } class test{ function __construct() { echo $this->addab(new em(),2); } function addab(em $j,$c) //这个方法,即可以在内部调用,也可以在外部调用。只要作用域许可。 十一、类的管理:1、instanceof关键字:用于分析一个对象是否是某一个类的实例或子类或是实现了某个特定的接口:如下例,但要注意: 类名没有任何引号等定界符,否则会出错。如test不能用'test' 3、返回类名:string get_class(object),成功时返回实例的类名,失败则返回FALSE: $a = new test2(); echo get_class($a); //返回 test2 4、了解类的公用属性:array get_class_vars(‘className'),返回关键数组:包含所有定义的public属性名及其相应的值。这个函数不能用实例名做变量 5、返回类方法:get_class_methods(‘test'); //或: get_class_methods($a);可用实例名做参数,返回包括构造函数在内的所有非私有方法。 6、print_r(get_declared_classes())了解当前PHP版本中所有的类名。PHP5有149个。 7、get_object_vars($a)返回实例中所有公用的属性及其值的关联数组。注意它和get_class_vars()的区别: 8、返回父类的名称:get_parent_class($b);//或get_parent_class(‘test2′); 返回test 9、确定接口是否存在:boolean interface_exists($string interface[,boolean autoload]) 10、确定对象类型: boolean is_a($obj,'className'),当$obj属于CLASSNAME类时,或属于其子类时,返回TRUE,如果$obj与class类型无关则返回FALSE。如:is_a($a,'test') 11、确定是否是某类的子对象:当$b是继承自TEST类时,返回TRUE,否则FALSE。boolean is_subclass_of($b,'test'); 12、确定类或实例中,是否存在某方法。method_exists($a,'getv') //或用method_exists(‘test','getv'),此函数适用于非public定义的作用域的方法。 以上函数实例: $a=new test(); 十一、自动加载类库文件:当类多了以后,比如要在一个文件中载入3个类库文件:a.class.php,b.class.php,c.class.php要用三个require_once(‘classes/a.class.php); require_once(‘classes/b.class.php); 可以用PHP5自动加载的功能来处理:在全局应用配置文件中,定义一个特殊的函数__autoload($class)函数(__autoload并不是一个类的方法,只是单独的函数,和类没有关系): 该函数放哪没有关系,在创建类实例时,也不必去调用这个autoload函数。PHP会自动完成。但务必注意一点:“在调用页面上创建实例所使用的类名称”、和“被调用的文件名”、以及“该文件中的类的名称”3个必须是一样的。这样就不需要去调用__autoload();如果不一样则必须单独调用__autoload(‘c');并给它一个文件名前缀。如: $m = new c(); //创建实例调用的类也是c 但如果c.class.php中的代码是: 类的家族化扩展:类的高级功能: 一、对象克隆:当克隆一个对象的实例时,其属性初始值继承了被克隆对象的当前值。代码如下:class test { public $p=5; function __clone(){ //只在克隆发生时起作用。用于改变在克隆时某些值 $this->p=15; } } $a=new test(); echo $a->p; $a->p=8; //如果没有__clone()方法影响,$b的P值将为8 $b = clone $a; echo $b->p; //15 二、对象继承:没有被声明为final的类可以被继承,没有被final和private界定的方法也可以继承,没有被private界定的属性也可以继承。当子类继承了父类或超类后,可以直接使用父类或超类(祖父类以及祖父的祖父)的所有允许的方法,属性。 (一)构造函数在继承中的特性: 1、当父类有构造函数而子类没有:则子类会在实例化时会自动执行父类的构造函数。这时如果要创建子类的实例,需要引入父类构造函数中所需的参数,否则出错。即使是“子类的子类”如果没有构造函数,也要在创建实例时输入其父类的父类的构造函数所需参数。PHP会从实例所在的子类会向上搜索合造的构造函数,一旦找到就停止,使用该构造函数。而不会再向上搜索,因此:子类本身如果没有构造函数,则以其最靠近的一个超类并且有构造函数的为准。 class cB extends cA{ Class cB execute success!'; }} class cC extends cB { Class cC FunC1!'; }} $b=new cB(‘Jack'); $b->name='John'; echo “$b->name : $b->age”; $b->funB1(); $c=new cC(); //这里会出错,由于cB也没有构造函数,因此再向上以cA为准,需要一个参数。改为$c=new cC(‘David');即可。 echo $c->name(); //David 2、当子类也有构造函数时:这时,不管父类是否有构造函数,都会执行子类自己的构造函数。 如上: 代码如下:class cB extends cA{ function __construct() { echo ‘ this is Class cB 's __construct!';} function funB1() { echo ‘ Class cB execute success!';} } 现在类CB有自己的构造函数时,这时创建实例$b=new cB(‘Jack');参数JACK不会起作用,因为父类CA的构造函数没有得到执行。因此$b->name和$->age就不会初始化值。需要另外赋值$b->name='Jack',$b->age=25; 如果这时要执行父类CA的构造函数,可以这样: 代码如下:function __construct($n) { parent::__construct($n); // 或:cA::__construct($n); echo ‘ this is Class cB 's __construct!';} 由于parent::__construct($n); 只会向上搜索父类的构造函数,一找到就停止且执行当前找到的构造函数,因此在上面例子中,如果parent::__construct($n)是用在最后一层的类cC中,并且类CB,CA都有构造函数,那么cC的实例只会执行cB的构造函数。不会执行cA。这时,如果CC的实例想都调用CA和CB的构造函数,有两种方法: A、在CB中也加入parent::__construct($n) this is Class cB 's __construct!';} (二)在子类中调用父类的属性或方法: 1、调用父类方法:在子类中调用父类的方法,有3种方法: 2、调用父类属性:只能用$this->ParentProperty; (三)重载: 在子类中,可以定义与父类相同属性或方法,改变父类该属性或方法的值或操作,称做重载。如: 三、接口:接口:interface,可以理解成一组功能的共同规范,最大意义可能就是在多人协作时,为各自的开发规定一个共同的方法名称。 和抽象类中的抽象方法一样: 1、不能在接口中对方法具体实现进行定义。而是由具体类来实现(而抽象类中的非抽象方法可以不必再定义,只有抽象方法和接口是一样要求要在具体类中实现)。 2、和抽象类一样,可以在接口中定义常量,并由具体类直接继承。 3、具体类必须实现抽象类的所有抽象方法(非抽象方法除外),同样,具体类如通过implements实现了接口后,必须完成接口中的所有方法。 接口实现过程:1、定义接口,2、用..implement X,Y,…和具体类对接。 class age implements Info //如要多个接口 class age (extends emJob) implements Info,interB… 在接口中定义的常量N的值是:'.$this::N.''; //直接继承接口中的常量值。} } $age=new age; 1、相关性:当创建的模型由一些紧密相关的对象采用时,用抽象。对于不相关对象采用的功能,用接口。 2、多重继承:PHP类可以继承多个接口,但不能扩展多个抽象类。 3、公共行为实现:抽象类可在其中实现公共的方法,但接口不行。 四、命名空间(PHP6)类库脚本A.inc.php和脚本B.inc.php中都一个类的名称为 class CNAME,并且这两个文件要在同一个文件如index.php中被调用。这时要用到命名空间。 步聚: 1、打开上面的A和B两个文件,分别在上面的最前面各加一行: namespace SPACEA; 和 namespace SPACEB; 名字自定。 2、在index.php中实例化类时,在类的前面添加命名空间和双冒号做为前缀: 这样就不会冲突了。 五、实现迭代器和迭代。参《PHP圣经》P142;
六、使用Reflection(反射)API 。简易实例:class a{ …. } $c = new ReflectionClass(‘a'); //PHP 内置类。 echo ‘ '.$c.''; 输出类a的结构和内容。参《PHP圣经》P145; (编辑:安卓应用网) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |
