深入分析php之面向对象


Posted in PHP onMay 15, 2013

以前对面向对象仅限于死记硬背型,工作这么久了,回过头来看又是一翻体悟,供大家看看。
1.final
final:php5新增一个final关键字。如果父类中的方法被声明为final,则子类无法覆盖该方法;如果一个类被声明final,则不能被继承。

class BaseClass{
     public function test(){
          ehco "test";
     }     final public function moreTest(){
          echo "moretest";
     }
}
class ChildClass extends BaseClass{
     public function moreTest(){
          echo "moretest";
     }
}
// 产生 Fatal error: Cannot override final method BaseClass::moretest()

2.__toString(建议用PHP5.2或者更高版本)
class Person{
     protected $name;
     protected $email;     public function setName($name){
          $this->name = $name;
     }
     public function setEmail($email){
          $this->email = $email;
     }
     public function __toString(){
          return "$this->name <$this->email>";
     }
}
$rasums = new Person;
$rasums->setName('test');
$rasums->setEmail('test@qq.com');
print $rasums;

3.接口和抽象类
接口的作用:你想要保证一个类按照特定的名称、可见性和原型实现一个或多个方法。
接口的要求:
     类中全部为抽象方法
     抽象方法钱不用加abstract
     接口抽象方法属性为public
     成员属性必须为常量
例:
interface ChildTest{
     public function childTest();
}
class FathTest implements ChildTest1,ChildTest2{
     public function childTest(){
          echo 1;
     }
     …………
}

抽象的作用: 其实抽象类和接口类有一部分很像,记得在哪里看见这样一句话,抽象类就把类像的部分抽出来,这句看上去很搞笑,其实它说出了抽象类的真理,抽象类的作用 是,当你发现你的很多类里面用很多方法你不断的在重复写,那你就可以考虑使用抽象类了,你可能会说“我不是可以重写一个类每个公共类我个实例化一个这个公 共类,调用相同的方法就可以了”,这里是可以,实际上抽象类做的工作也就是这个,不过他省去了你实例化的这个步骤,让你就像直接调用本类方法一样方便,而 且你还可以重载这个方法。
抽象的要求:
     类中至少有一个抽象方法
     抽象方法钱必须加abstract
例:
abstract class Database{
     abstract public function connect();
     abstract public function query();
     abstract public function fetch();
     abstract public function close();
}

注:抽象方法不能定义为私有方法、不能定义为最终方法,因为它们需要被继承。

4.传递对象引用
php4:所有“=”都是创建一个副本
php5:除了对象外,其他“=”进行赋值时,都是创建一个副本;而对象则是引用

5.克隆对象
一、
聚合类:
__call方法简介:
当客户端代码用类中未定义的方法时,__call会被调用。
__call()接受两个参数,一个是方法名称,另一个是传递给要调用方法的所有参数(包括数组)
__call()方法返回的任何值都会返回给客户,将好像调用方式真实存在一样
例:

class Address{
     protected $city;
     protected $country;
     public function setCity($city){$this->city = $city;}
     public function getCity(){return $this->city;}
     public function setCountry($country){$this->country = $country;}
     public function getCountry(){return $this->country;}
}
class Person{
     protected $name;
     protected $address;
     //浅克隆
     public function __construct(){
          $this->address = new Address;
     }
     public function setName($name){
          $this->name = $name;
     }
     public function getName(){
          return $this->name;
     }
     public function __call($method,$arguments){
          if(method_exists($this->address,$method)){
               return call_user_func_array(array($this->address,$method),$arguments);
          }
     }
     //深克隆
     public function __clone(){
          $this->address = clone $this->address;
     }
}
$test1 = new Person;
$test2 = clone $test1;
$test1->setName('testname1');
$test1->setCity('testcity1');
$test2->setName('testname2');
$test2->setCity('testcity2');
echo $test1->getName().'-'.$test1->getCity()."\n";
echo $test2->getName().'-'.$test2->getCity()."\n";
//testname1-testcity2
//testname2-testcity2

6.重要属性访问(__set __get __isset __unset) __isset __unset5.1之后才有用
作用:拦截对属性的需求,为了提高分离的程度,还要实现__isset()和__unset(),以便当我们用isset来检测属性或者unset()来删除属性,来保证类的行为正确
例:
class Person{
     protected $__data = array('email','test');
     public function __get($property){
          if(isset($this->__data[$property])){
               return $this->__data[$property];
          }else{
               return false;
          }
     }
     public function __set($property,$value){
          if(isset($this->__data[$property])){
               return $this->__data[$property] = $value;
          }else{
               return false;
          }
     }
     public function __isset($property){
          if(isset($this->__data[$property])){
               return true;
          }else{
               return false;
          }
     }
     public function __unset($property){
          if(isset($this->__data[$property])){
               return unset($this->__data[$property]);
          }else{
               return false;
          }
     }
}
$test = new Person;
$test->email= 'test';
var_dump($test->email);

注意:
     这两个方法只会捕捉缺少的属性,如果你为你的类定义了一个属性,那么当访问这个属性时php不会调用__get()和__set();
     这两个方法完全破坏了任何属性继承的想法。如果父对象中有个 __get()方法,而你在子类中又实现了自己的__get()方法,那么你的对象不会正确的执行,因为父类的__get()方法永远不会被调用,当然可以用parent::__get()解决
缺点:
     速度相对较慢
     使用魔术访问器方法就不可能在使用反射类,如phpdocumentor这类的工具将代码自动文档化
     不能将其用于静态属性
PHP 相关文章推荐
删除无限级目录与文件代码共享
Jul 12 PHP
通过对服务器端特性的配置加强php的安全
Oct 09 PHP
支持数组的ADDSLASHES的php函数
Feb 16 PHP
提高PHP性能的编码技巧以及性能优化详细解析
Aug 24 PHP
php读取excel文件的简单实例
Aug 26 PHP
使用PHP导出Word文档的原理和实例
Oct 21 PHP
PHP中VC6、VC9、TS、NTS版本的区别与用法详解
Oct 26 PHP
php显示指定目录下子目录的方法
Mar 20 PHP
PHP动态地创建属性和方法, 对象的复制, 对象的比较,加载指定的文件,自动加载类文件,命名空间
May 06 PHP
针对多用户实现头像上传功能PHP代码 适用于登陆页面制作
Aug 17 PHP
PHP正则验证字符串是否为数字的两种方法并附常用正则
Feb 27 PHP
php反射学习之不用new方法实例化类操作示例
Jun 14 PHP
深入解析php之apc
May 15 #PHP
深入解析php之sphinx
May 15 #PHP
基于php设计模式中单例模式的应用分析
May 15 #PHP
基于php设计模式中工厂模式详细介绍
May 15 #PHP
php笔记之:数据类型与常量的使用分析
May 14 #PHP
PHP笔记之:基于面向对象设计的详解
May 14 #PHP
php在window iis的莫名问题的测试方法
May 14 #PHP
You might like
php学习笔记之面向对象编程
2012/12/29 PHP
php生成数组的使用示例 php全组合算法
2014/01/16 PHP
php阻止页面后退的方法分享
2014/02/17 PHP
解决nginx不支持thinkphp中pathinfo的问题
2015/07/21 PHP
Zend Framework框架路由机制代码分析
2016/03/22 PHP
thinkPHP使用pclzip打包备份mysql数据库的方法
2016/04/30 PHP
datePicker——日期选择控件(with jquery)
2007/02/20 Javascript
jsTree树控件(基于jQuery, 超强悍)[推荐]
2009/09/01 Javascript
基于Jquery的淡入淡出的特效基础练习
2010/12/13 Javascript
JS禁用页面上所有控件的实现方法(附demo源码下载)
2015/12/17 Javascript
JS实现页面数据无限加载
2016/09/13 Javascript
关于Javascript中document.cookie的使用
2017/03/08 Javascript
vue父组件通过props如何向子组件传递方法详解
2017/08/16 Javascript
纯js实现画一棵树的示例
2017/09/05 Javascript
Vue2.0 给Tab标签页和页面切换过渡添加样式的方法
2018/03/13 Javascript
vue模仿网易云音乐的单页面应用
2019/04/24 Javascript
vue轮播组件实现$children和$parent 附带好用的gif录制工具
2019/09/26 Javascript
全面解析js中的原型,原型对象,原型链
2021/01/25 Javascript
[48:44]2014 DOTA2国际邀请赛中国区预选赛5.21 TongFu VS HGT
2014/05/22 DOTA
20招让你的Python飞起来!
2016/09/27 Python
python中reload(module)的用法示例详解
2017/09/15 Python
更换Django默认的模板引擎为jinja2的实现方法
2018/05/28 Python
彻彻底底地理解Python中的编码问题
2018/10/15 Python
Django组件cookie与session的具体使用
2019/06/05 Python
wxpython+pymysql实现用户登陆功能
2019/11/19 Python
在django中使用apscheduler 执行计划任务的实现方法
2020/02/11 Python
打印tensorflow恢复模型中所有变量与操作节点方式
2020/05/26 Python
Python如何执行系统命令
2020/09/23 Python
英国工作场所设备购买网站:Slingsby
2019/05/03 全球购物
说出一些常用的类,包,接口
2014/09/22 面试题
合同专员岗位职责
2013/12/18 职场文书
出国留学担保书
2014/05/20 职场文书
党员个人剖析材料
2014/09/30 职场文书
2015年城市管理工作总结
2015/05/23 职场文书
辩论赛开场白大全(主持人+辩手)
2015/05/29 职场文书
MySQL的表级锁,行级锁,排它锁和共享锁
2022/07/15 MySQL