高级phpv5对象研究

高级php v5 对象研究 本文介绍了php v5一些更高级的面向设计的特性。其中包括各种对象类型,它们允许将系统中的组件相互分离,创建可重用、可扩展、可伸缩的代码。   领会暗示   首先介绍一下对象类型和类型提示的优点。一个类定义一种类型。从该类实例化的任何对象属于该类定义的类型。所以,使用 car 类创建 car 对象。如果 car 类继承 vehicle 超类,则 car 对象还将是一个 vehicle 对象。这反映了我们在现实世界中分类事物的方法。但正如您将看到的,类型不仅仅是分类系统元素的有用方法。类型是面向对象编程的基础,因为类型是良好一致的行为的保证。许多设计技巧来自该保证。   “开始了解 php v5 中的对象”展示对象为您保证了接口。当系统传递 dictionary 对象时,您可以确定它具有 $translations 数组和 summarize() 方法。相反,关联数组不提供相同级别的确定性。要利用类提供的清晰接口,需要知道您的对象实际上是 dictionary 的一个实例,而不是某个 imposter。可以用 instanceof 操作符来手动验证这一点,该操作符是 php v5 引入的介于对象实例和类名之间的一个便捷工具。    instanceof dictionary   如果给定对象是给定类的实例,则 instanceof 操作符解析为真。在调用方法中第一次遇到 dictionary 对象时,可以在使用它之前检查它的类型。 if ( $en instanceof dictionary ) {  print $en->summarize(); }   但是,如果使用 php v5 的话,可以将对象类型检查构建到类或方法声明中。   在“开始了解 php v5 中的对象”中,重点介绍两个类:dictionary,它存储术语和翻译, dictionaryio,它将 dictionary 数据导出(导入)自(至)文件系统。这些特性使得将 dictionary 文件发送到第三方翻译器变得容易,第三方翻译器可以使用自己的软件来编辑数据。然后,您可以重新导入已处理的文件。清单 1 是 dictionary 类的一个版本,它接受一个 dictionaryio 对象,并将其存储以备将来使用。   清单 1. 接受 dictionaryio 对象的 dictionary 类的一个版本 class dictionary {  public $translations = array();  public $type =”en”;  public $dictio;  function adddictionaryio( $dictio ) {   $this->dictio=$dictio;  }  function export() {   if ( $this->dictio ) {    $this->dictio->export( $this );   }  } } class dictionaryio {  function export( $dict ) {   print “exporting dictionary data “.”($dict->type)
“;  } } $en = new dictionary(); $en->adddictionaryio( new dictionaryio() ); $en->export(); // output: // dumping dictionary data (en)   dictionaryio 类具有单个方法 export(),它接受一个 dictionary 对象,并使用它来输出假消息。现在,dictionary 具有两个新方法:adddictionaryio(),接受并存储 dictionaryio 对象; export(),使用已提供的对象导出 dictionary 数据 —— 或者是在完全实现的版本中。   您可能会疑惑为什么 dictionary 对象不仅实例化自己的 dictionaryio 对象,或者甚至在内部处理导入导出操作,而根本不求助于第二个对象。一个原因是您可能希望一个 dictionaryio 对象使用多个 dictionary 对象,或者希望存储该对象的单独引用。另一个原因是通过将 dictionaryio 对象传递给 dictionary,可以利用类切换或 多态性。换句话说,可以将 dictionaryio 子类(比如 xmldictionaryio)的实例传递给 dictionary,并更改运行时保存和检索数据的方法。   图 1 显示了 dictionary 和 dictionaryio 类及其使用关系。

\

正如所显示的,没有什么阻止编码器将完全随机的对象传递给 adddictionaryio()。只有在运行 export() 时,才会获得一个类似的错误,并发现已经存储在 $dictio 中的对象实际上并没有 export() 方法。使用 php v4 时,必须测试本例中的参数类型,以绝对确保编码器传递类型正确的对象。使用 php v5 时,可以部署参数提示来强制对象类型。只将所需的对象类型添加到方法声明的参数变量中,如清单 2 所示:

  清单 2. 将对象类型添加到方法声明的参数变量中

function adddictionaryio( dictionaryio $dictio ) { $this->dictio=$dictio;}

function export() { if ( $this->dictio ) {  $this->dictio->export( $this ); }}

  现在,如果客户机编码器试图将类型错误的对象传递给 adddictionaryio(),php 引擎将抛出一个致命错误。因此,类型提示使得代码更安全。不幸的是,提示仅对对象有效,所以不能在参数列表中要求字符串或整数。必须手动测试这些原类型。

  即使可以保证 adddictionaryio() 将获得正确的对象类型,但不能保证该方法被首先调用。export() 方法测试 export() 方法中 $dictio 属性的存在,从而避免错误。但您可能希望更严格一些,要求 dictionaryio 对象传递给构造函数,从而确保 $dictio 总是被填充。

  调用覆盖方法

  在清单 3 中,xmldictionaryio 集成 dictionaryio。而 dictionaryio 写入并读取序列化数据,xmldictionaryio 操作 xml,可以与第三方应用程序共享。xmldictionaryio 可以覆盖其父方法(import() 和 export()),也可以选择不提供自己的实现(path())。如果客户机调用 xmldictionaryio 对象中的 path() 方法,则在 dictionaryio 中实现的 path() 方法被调用。

  事实上,可以同时使用这两种方法。可以覆盖方法并调用父实现。为此,使用新关键字 parent。用范围解析操作符和所讨论方法的名称来使用 parent 。例如,假设需要 xmldictionaryio 使用当前工作目录(如果有一个可用)中叫做 xml 的目录;否则,它应使用由父 dictionaryio 类生成的默认路径,如清单 3 所示:

  清单 3. xmldictionaryio 使用 xml 目录或由 dictionaryio 类生成的默认路径

class xmldictionaryio extends dictionaryio {

 function path( dictionary $dictionary, $ext ) {  $sep = directory_separator;  if ( is_dir( “.{$sep}xml” ) ) {   return “.{$sep}xml{$sep}{$dictionary->gettype()}.$ext”;  }  return parent::path( $dictionary, $ext ); }// …

  可以看到,该方法检查本地 xml 目录。如果该测试失败,则它使用 parent 关键字指派给父方法。

本新闻共3页,当前在第1页 1 2 3

子类和构造函数方法   parent 关键字在构造函数方法中尤其重要。如果在子类中不定义构造函数,则 parent 构造函数代表您被显式调用。如果在子类中不创建构造函数方法。则调用父类的构造函数并传递任何参数是您的责任,如清单 4 所示:   listing 4. invoking the parent class’s constructor class specialdictionary extends dictionary {  function __construct( $type, dictionaryio $dictio, $additional ) {   // do something with $additional   parent::__construct( $type, $dictio );  } } 抽象类和方法   虽然在父类中提供默认行为是完全合法的,但这可能不是最巧妙的方法。对于启动器,您必须依赖子类的作者来理解它们必须实现 import() 和 export(),才能在 broken 状态创建类。而且,dictionaryio 类实际上是兄弟,而不是父子。xmldictionaryio 不是 dictionaryio 的特例;相反,它是一种备选实现。   php v5 允许定义部分实现的类,其主要角色是为它的子女指定核心接口。这种类必须声明为抽象。 abstract class dictionaryio {}   抽象类不能实例化。必须创建子类(即,创建继承它的类),并创建该子类的实例。可以在抽象类中声明标准和抽象方法,如清单 5 所示。抽象方法

http://www.bkjia.com/phpjc/532425.htmlwww.bkjia.comtruehttp://www.bkjia.com/phpjc/532425.htmltecharticle高级phpv5对象研究 本文介绍了phpv5一些更高级的面向设计的特性。其中包括各种对象类型,它们允许将系统中的组件相互分离,创建可重用…

Posted in 未分类