当前位置:  首页  >  PHP教程  >  PHP 安全  >  防注入

PHP5.0中多态性的实现计划浅析

至此,你应当基础懂得什么是多态性以及为什么PHP5在实现多态性方面并不完善。一般说来,你应当知道如何用一个多态性对象模型来封装有条件的行动。当然,这样会提高你的对象的机动性,并且意味着更少的代码实现。另外,通过封装满足必定条件的行动(具体要依附于对象的状态),你还提高了代码的明白程度
提要:本文将讨论多态性的概念及其在面向对象设计中的利用,还将分析如何在PHP 5中应用多态性以及存在的优毛病。

  PHP的最新发行版本中已经实现了对迟绑定的支撑。当然,在应用其迟绑定功效时还存在很多标题。假如你应用的是更旧版本的PHP(我的服务器上运行的是PHP 5.0.1版本),那么你可能发明其中缺乏对于迟绑定的支撑。因此,请留心本文中的代码有可能无法工作在你特定的PHP 5版本中。

  一、 PHP 5和多态性

  本文想讨论面向对象编程中最为重要的部分之一--多态性的设计。为了阐明标题,我应用了PHP 5。在你持续浏览之前,请首先明白本文并不是完整有关于PHP的。尽管这种语言在以前的两个重要版本中在快速开发方面已经取得很大的提高,但是,在其与更为成熟的语言如C 或者Java相匹敌之前,它对于对象的支撑还要经历一段过程。

  假如你是一位面向对象编程的进门者,那么本文可能不合适你,由于多态性这部分知识比拟特别:一旦懂得了它,你将永远不会忘记。假如你想简略懂得一点对象编程和设计知识,并且当某人说'某个对象是多态的'时,还不十分明白这是什么意思的话,那么本文正合适你。
到本文最后,你应当知道什么是多态性以及如何把它利用到面向对象的设计中,并且你会懂得PHP 5中对象编程的长处与不足。 

  二、什么是多态性?

  多态性,其来自于dictionary.com的定义是'以不同情势,阶段或者类型呈现在独立的组织中或者同种组织中,而不存在基本差别。'由该定义,我们可以认为,多态性是一种通过多种状态或阶段来描写雷同对象的编程方法。实在,它的真正意义在于:实际开发中,我们只需要关注一个接口或基类的编程,而不必担心一个对象所属于的具体类(class)。

  假如你熟悉设计模式,即使只是有个初步懂得,那么你也会懂得这个概念。事实上,多态性可能是基于模式设计编程中的最巨大的工具。它答应我们以一种逻辑的方法来组织相类似的对象从而实现在具体编码时不必担心对象的具体类型;而且,我们只需要对一个所期看的接口或基类编程即可。一个利用程序越抽象,则它就显得越机动--而多态性是对行动加以抽象的最好的方法之一。

  例如,让我们考虑一个叫Person的类。我们可以用称为David,Charles和Alejandro的类来子类化Person。Person有一个抽象方法AcceptFeedback(),所有的子类都要实现这个方法。这意味着,任何应用基类Person的子类的代码都能调用方法AcceptFeedback()。你不必检查该对象是一个David还是一个Alejandro,仅知道它是一个Person就够了。成果是,你的代码只需关注'最小公分母'-Person类即可。 


在这个示例中的Person类也可以被创立为一个接口。当然,与上面相比存在一些差别,重要在于:一个接口并没有给出任何行动,而仅断定了一组规矩。一个Person接口请求的是'你必需支撑AddFeedback()方法',而一个Person类可以供给一些AddFeedback()方法的缺省代码-你对之的懂得可以是'假如你不选择支撑AddFeedback(),那么你应当供给一种缺省实现。'至于如何选择接口或基类则并非本文的主题;但是,一般说来,你需要通过基类来实现一个缺省的方法。假如你能够简略地勾勒出你的类所要实现的一组期看的功效,那么你也可以应用一个接口。

  三、利用多态性设计

  我们将持续应用Person基类的例子,现在让我们分析一个非多态性的实现。下列示例中应用了不同类型的Person对象--这是一种非常不幻想的编程方法。留心,实际的Person类被省略。目前为止,我们仅关心代码调用的标题。

<?php
 $name = $_SESSION['name'];
 $myPerson = Person::GetPerson($name);
 switch (get_class($myPerson)){
  case 'David' :
   $myPerson->AddFeedback('Great Article!','Some Reader', date('Y-m-d'));
   break;
  case 'Charles':
   $myPerson->feedback[] = array('Some Reader', 'Great Editing!');
   break;
  case 'Alejandro' :
   $myPerson->Feedback->Append('Awesome Javascript!');
   break;
  default :
   $myPerson->AddFeedback('Yay!');
 }
?>
  这个示例展现了行动不同的对象,还有一个switch语句用于区分不同的Person类对象,从而履行其各自相应的准确把持。留心,这里针对不同条件的回馈注释是不同的。在实际利用程序开发中可能不会呈现这种情况;我仅为了简略地阐明类实现中存在的差别。 

  下面的一个示例应用了多态性。

<?php
 $name = $_SESSION['name'];
 $myPerson = Person::GetPerson($name);
 $myPerson->AddFeedback('Great Article!', 'SomeReader', date('Y-m-d'));
?>
  留心,这里没有switch语句,而最重要的是,缺乏有关Person::GetPerson()会返回什么类型的对象。而另一个Person::AddFeedback()是一个多态方法。行动完整是由具体类进行封装的。请记住,在此无论我们应用的是David,Charles还是Alejandro,调用代码从不必懂得具体类的功效,而仅知道基类就可以了。

  尽管我的示例并不完善,但是,从调用代码的角度,它已经展现了多态性的基础用法。现在我们需要分析这些类的内部实现。从一个基类进行派生的一个最巨大的处所在于,该派生类能够存取父类的行动,这种情况经常是缺省的实现,但是也可能呈现在类持续链中用于创立更为复杂的行动。下面是这种情况的一个简略展现。


<?php
class Person{
 function AddFeedback($comment, $sender, $date){
  //把回馈添加到数据库
 }
}
class David extends Person{
 function AddFeedback($comment, $sender){
  parent::AddFeedback($comment, $sender,
  date('Y-m-d'));
 }
}
?>


  在此,David类中的AddFeedback方法实现中首先调用了Person::AddFeedback方法。你可能留心到,它模仿了C ,Java或C#中的方法重载。请记住,这仅是一个简略化的示例,并且你编写的实际代码完整依附于你的实际工程。

  四、PHP 5中的迟绑定

  依我的见解,迟绑定正是使得Java和C#如此引人注视标重要原因。它们答应基类方法用'this'或$this来调用方法(即使它们不存在于基类中或调用一个基类中的方法,它有可能为持续类中的另一个版本所代替)。你可以认为如下的实现在PHP中是答应的:

<?php
class Person{
 function AddFeedback($messageArray) {
  $this->ParseFeedback($messageArray);
  //写向数据库
 }
}
class David extends Person{
 function ParseFeedback($messageArray){
  // 进行一些分析
 }
}
?>
  记住,在Person类中并没有ParseFeedback。现在,假定你拥有这一部分实现代码(为了本例阐明标题起见),那么这会导致$myPerson成为一个David对象:

<?php
$myPerson = Person::GetPerson($name);
$myPerson->AddFeedback($messageArray);
?>
  呈现分析错误!大致错误信息为,方法ParseFeedback并不存在或者一些类似的信息。关于PHP 5中的迟绑定我们就讨论这些!下面我们再回纳一下迟绑定的概念。

  迟绑定意味着,方法调用在最后时刻才绑定到目标对象。这意味着,当该方法被运行时刻调用时,那些对象已经有了一种具体类型。在我们上面的示例中,你调用了David::AddFeedback(),而既然David::AddFeedback()中的$this引用一个David对象,那么你可以逻辑地假定ParseFeedback()方法是存在的--但事实上它并不存在,由于AddFeedback()是在Person中定义的,并且从Person类中调用ParseFeedback()。
不幸的是,没有简略的方法来打消PHP 5中的这种行动。这意味着,当你想创立一个机动的多态类层次时你可能有点无能为力。

  我必需指出,我选择PHP 5作为本文的表达语言仅仅是由于:这种语言并没有实现对象概念的完善抽象!由于PHP 5还处于其测试版本运行期,所以这是可以体谅的。另外,既然该语言中参加了抽象类和接口,迟绑定也应当被实现。

  五、小结

  至此,你应当基础懂得什么是多态性以及为什么PHP 5在实现多态性方面并不完善。一般说来,你应当知道如何用一个多态性对象模型来封装有条件的行动。当然,这样会提高你的对象的机动性,并且意味着更少的代码实现。另外,通过封装满足必定条件的行动(具体要依附于对象的状态),你还提高了代码的明白程度。 


吐了个 "CAO" !
扫码关注 PHP1 官方微信号
PHP1.CN | 中国最专业的PHP中文社区 | PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | PHP问答
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved PHP1.CN 第一PHP社区 版权所有