retweet

细致学习php5的OO特性[1]

尽管开发和运行环境已经是php5了,但是一直没有使用php5的OO特性写代码。现在终于有机会拿着研究C++ OOP的精神,研究PHP5的OO特性。本文设计到一些细节,有些代码仅仅为了测试,有意为之,不要见笑。

  • *This 伪变量。*
从PHP手册中看到这样一句话,一开始有些不理解。 | $this 是一个到调用对象(通常是方法所属于的对象,但也可以是另一个对象,如果该方法是从第二个对象内静态调用的话)的引用。 源文档 <http://php.chinaunix.net/manual/zh/language.oop5.basic.php> |
于是做了这样的例子:
|@class ClassB{ const NAME = "Class B"; public $a = ClassB::NAME; public function foo(){ echo $this->a.":: foo call\n"; echo "'this' is a {$this->a} object\n"; } }; class ClassA{ const NAME = "class A"; public $a = ClassA::NAME; public function createB(){ return new ClassB(); } public function foo(){ echo $this->a.":: foo call\n"; echo "\n\nCall a object function\n"; $this->createB()->foo(); echo "\n\n function called statically \n"; ClassB::foo(); } } $A = new ClassA(); $A->foo(); ?> @ |
发现在ClassA里面直接以ClassB::foo();的形式“静态调用”,ClassB::foo();里面的this的确是对象$A的引用。 注意是“静态调用(called statically)”而非静态方法。经过测试,静态方法内不允许this伪变量。
  • *Extends *
上面的特性-- *在方法被静态调用的上下文环境中,this是调用者的引用*,这个特性可以应用到多级继承时,提供子类访问基类的途径:
| @class BaseClass { // Redefine the parent method public final $abc = "Base"; function displayVar() { echo "this->abc:".$this->abc."\n"; echo "Base class\n"; parent::displayVar(); } } class SimpleClass extends BaseClass { public $abc = "SimpleClass"; // Redefine the parent method function displayVar() { echo "this->abc:".$this->abc."\n"; echo "SimpleClass class\n"; } } class ExtendClass extends SimpleClass { public $abc = "ExtendClass"; // Redefine the parent method function displayVar() { echo "this->abc:".$this->abc."\n"; echo "Extending class\n"; parent::displayVar(); BaseClass::displayVar(); } } $extended = new ExtendClass(); $extended->displayVar(); ?> 输出:@@ @

./test_extends.php

this->abc:ExtendClass

Extending class

this->abc:ExtendClass

SimpleClass class

this->abc:ExtendClass

Base class |

  • *construct *
PHP的__construct不是太严格,甚至允许$obj->__construct , 当然这也可能是为了兼容以前的代码。 但是下面的测试很意外,ClassA::__construct()的调用引起php croe dump了。
我的php版本: php -v

PHP 5.2.1 (cli) (built: Apr 28 2007 15:27:26)

Copyright (c) 1997-2007 The PHP Group

Zend Engine v2.2.0, Copyright (c) 1998-2007 Zend Technologies

  • * destruct*
从手册看到一句话:
@class ClassAAA{ function __construct() { echo "ClassA::__construct\n"; } }; ClassAAA::__construct(); ?> @ |
|

注意: 试图在析构函数中抛出一个异常会导致致命错误。

源文档 <http://php.chinaunix.net/manual/zh/language.oop5.decon.php> |

这是因为对象的析构时机依赖php的实际实现,可能在php销毁对象的时候,代码块已经不在我们的try catch控制中了。 对于我下面测试的这个版本,php在一个对象的引用计数为0时,立即调用析构函数进行销毁,所以有幸能捕获到析构函数内的异常。 但是手册里面的这个“注意”是对的,因为php没有明确定义析构函数执行的时机,所以我们不应该在析构函数中抛出异常。
|@class MyDestructableClass { function __construct() { print "In constructor\n"; $this->name = "MyDestructableClass"; } function __destruct() { print "Destroying " . $this->name . "\n"; throw new Exception("my error"); } } function abc(){ try{ try{ $obj = new MyDestructableClass(); //return $obj; } catch(Exception $e){ echo "abc::".$e->getMessage(); } } catch(Exception $e){echo "abc::".$e->getMessage();} //echo("abc fun run\n"); } try{ abc(); } catch(Exception $e){ echo "main::".$e->getMessage(); } try{ unset($r); } catch(Exception $e){ echo "main 2::".$e->getMessage(); } ?> @ |
【未完待续】
--EOF--

若无特别说明,本站文章均为原创,转载请保留链接,谢谢

本文地址: http://www.dulao5.com/php/2007/08/22/php5-oo-featrues.textile