| 作者:佚名 文章来源:不详 点击数: 更新时间:2007-2-2 10:04:59 |
|
rintConstant()是显示常量constant_value的值,但是,constant_value存在于global空间和Class内这两个地方。在这种情况下,MyClass内的常量constant_value的优先级较高,被显示为「class constant」。
■对象变量
即使是在类没有被实例化状态下,对象变量也能准确的按照指定的值被初始化。访问的方法如下:
类名::$变量名
PHP代码:--------------------------------------------------------------------------------
class Hoge { static $my_static = 5; }
print Hoge::$my_static; ?>
--------------------------------------------------------------------------------
■统一构建器
在生成对象的时候,能够自动被调用的方法被称作“构建器”。
PHP4中的构建器,是与Class名相同的方法名。这是与Java和C++相同的地方,因此,对于一些用惯了的人来说,不会有别扭感。但是,如果要从子类中调用父类的构建器的话,在PHP中就必须特意写上父类的名字。
在PHP中,父类的构建器不能被自动调用,因此,情况就比较多。 在PHP5中,统一采用了__constructor这个构建器名称,不管class名是什么,凡是被称为__construct()的,都被当作构建器来处理。
另外,考虑到同PHP4的互换性,假如存在于Class名相同的以前的构建器名,那么,优先使用那个构建器。
PHP代码:--------------------------------------------------------------------------------
class BaseClass { function __construct() { print "In BaseClass constructor\n"; } }
class SubClass extends BaseClass { function __construct() { parent::__construct(); print "In SubClass constructor\n"; } }
$obj = new BaseClass(); $obj = new SubClass(); ?>
--------------------------------------------------------------------------------
■析构函数
与构建器相反,能够在对象释放时自动被调用的方法被称为析构函数。
PHP4支持析构函数,通过登录在PHP运行终止时用register_shutdown_function()调用的函数,只有类似的实行方法。PHP5正式支持析构函数,能够在类中指定对象释放时的动作。
析构函数就是名为__destruct的方法。当对象内部的参照计数器变成0的时候,__destruct()被调用,然后对象所使用的内存被释放出来。
PHP代码:--------------------------------------------------------------------------------
class MyDestructableClass { function __construct() { print "In constructor\n"; $this->name = 'MyDestructableClass'; }
function __destruct() { print 'Destroying ' . $this->name . "\n"; } }
$obj = new MyDestructableClass(); ?>
--------------------------------------------------------------------------------
另外,与构建器相同的地方是,父类的析构函数不能被自动的调用,必要的时候,需要用命令:
parent::__destruct();
■访问
在PHP4中,如果访问了一个不存在的属性,那么系统就会自动生成与之相对应的新属性。
PHP代码:-------------------------------------------------------------------------------- class Hoge { }
$obj = new Hoge; $obj->prop = "This is new property";
--------------------------------------------------------------------------------
如上所示,当把值代入一个不存在的属性时,那个代入点就会自动生成一个新属性。同样的,访问一个不存在的属性,就如同被代入NULL值的变量一样,不会发生错误。
在PHP5中追加了一点,就是能够对访问任意的属性进行控制。在类中如果存在__set()、__get()这样的方法,替代上述的动作此处的方法将能够被调用。例如:
PHP代码:--------------------------------------------------------------------------------
class Hoge { function __set($name, $value) { print "__set() is called with ($name, $value)\n"; $this->$name = $value; } }
$obj = new Hoge;
$obj->a = '123'; $obj->a = '456'; $obj->b = '789'; ?>
--------------------------------------------------------------------------------
在这里,__set 方法被作为未定义属性的代入方法,在显示值之后将值代入未定义属性。
PHP代码:-------------------------------------------------------------------------------- $obj->a = '123';
--------------------------------------------------------------------------------
执行这一句时,因为在这个时候不存在属性a,因此,作为代替,__set 方法被调用。
__set() is called with (a, 123)
其次,
$obj->a = '456';
再一次的代入$obj->a,这一次,由于属性a已经存在,所以__set 没有被调用,和通常一样把值代入到了属性a中去了。
$obj->b = '789';
这一回,我们把值代入另一个属性b中,同a的第一次情况一样,
__set() is called with (b, 789)
同__set 方法相反,__get 方法是在对不存在的属性的引用时调用的。将这两者结合起来,再来看一下对于属性的访问,实际上,利用它能够写出在不同的场合都能做出不同响应的类来。
PHP代码:--------------------------------------------------------------------------------
class Hoge { public $properties;
function __set($name, $value) { $this->properties[$name] = $value; } function __get($name) { return $this->properties[$name]; } }
$obj = new Hoge;
$obj->a = '123'; $obj->b = '456'; echo $obj->a; echo $obj->b;
print_r($obj); ?>
--------------------------------------------------------------------------------
在这个例子里,对类中所有属性的访问被装入了$properties中,这样,使我们加入的属性不直接的附在对象之下。这是个不太能容易理解的例子,例如,试着把这个例子中的保存到$properties改成存入文件或是数据库会很有趣吧。实际上,在对象里面,我们能够简单的实现让许多的复杂的操作。
与__set, __get多少有些不同,但是__call也能用来书写不存在的方法,当我们向如下例子一样调用对象的方法的时候,
$object->methodname();
如果这个类中不存在methodname这个方法,通常情况下,就会出现如下错误:
Fatal error: Call to undefined method Class::methodname()
但是,如果这个类中存在__call这个方法,作为替代,__call就被调用。__call的参数有两个,第一个参数是被叫出的方法名,第二个参数是保持了的被调用的参数的数组。考虑到有很多的使用方法,除了以下的例子外,还可以使用其它的方法。
PHP代码:--------------------------------------------------------------------------------
class Proxy { private $object;
function __call($name, $params) { if (isset($this->object)) { if (method_exists($this->object, $name)) { return call_user_func_array(array($this->object, $name), $params); } else { return "method not exists."; } } } function __construct($object) { $this->object = $object; } }
class Hoge { function add($var1, $var2) { return $var1 + $var2; } }
$p = new Proxy(new Hoge);
$result = $p->add(1, 2); echo "result: $result \n";
$result = $p->sub(5, 3); echo "result: $result \n"; ?>
全新的对象模型 PHP中的对象处理部分已完全重写,具有更佳的性能和更多的功能。在PHP的以前版本中,对象与内建变量类型(如integer和string)的处理方法相同,其弊端是当变量被赋值为对象或对象作为参数传递时,得到的是对象复制品。而在新版本中,对象通过句柄进行引用,而不是通过它的值。(句柄可以认是为是对象的标识符) 很多PHP程序员可能未意识到以前的对象模型的“复制怪癖”,因此以前的PHP程序将不需要做任何更改,或只做很小的改动即可运行 私有和保护成员 PHP 5引入了私有和保护成员变量,它们可以定义类属性在何时可以被访问。 例 类的保护成员变量能在该类的扩展类中被访问,而私有成员变量只能在本类中被访问。 class MyClass { private $Hello = "Hello, World!\n"; protected $Bar = "Hello, Foo!\n"; protected $Foo = "Hello, Bar!\n";
function printHello() { print "MyClass::printHello() " . $this->Hello; print "MyClass::printHello() " . $this->Bar; print "MyClass::printHello() " . $this->Foo; } }
class MyClass2 extends MyClass { protected $Foo;
function printHello() { MyClass::printHello(); /* Should print */ print "MyClass2::printHello() " . $this->Hello; /* Shouldn't print out anything */ print "MyClass2::printHello() " . $this->Bar; /* Shouldn't print (not declared)*/ print "MyClass2::printHello() " . $this->Foo; /* Should print */ } }
$obj = new MyClass(); print $obj->Hello; /* Shouldn't print out anything */ print $obj->Bar; /* Shouldn't print out anything */ print $obj->Foo; /* Shouldn't print out anything */ $obj->printHello(); /* Should print */
$obj = new MyClass2(); print $obj->Hello; /* Shouldn't print out anything */ print $obj->Bar; /* Shouldn't print out anything */ print $obj->Foo; /* Shouldn't print out anything */ $obj->printHello(); ?>
私有和保护方法 在PHP 5(ZEND引擎2)中,还引入了私有和保护方法。 例: class Foo { private function aPrivateMethod() { echo "Foo::aPrivateMethod() called.\n"; }
protected function aProtectedMethod() { echo "Foo::aProtectedMethod() called.\n"; $this->aPrivateMethod(); } }
class Bar extends Foo { public function aPublicMethod() { echo "Bar::aPublicMethod() called.\n"; $this->aProtectedMethod(); } }
$o = new Bar; $o->aPublicMethod(); ?> 以前代码中的用户自定义类或方法中虽未定义"public," "protected" 或 "private"等关键字,但无需编辑即可运行。 抽象类和方法 PHP 5还引入了抽象类和方法。抽象方法只声明方法定义, 不供实际运行。包含抽象方法的类需要声明为抽象类。 例: abstract class AbstractClass { abstract public function test(); }
class ImplementedClass extends AbstractClass { public function test() { echo "ImplementedClass::test() called.\n"; } }
$o = new ImplementedClass; $o->test(); ?> 抽象类不能实例化。以前代码中的用户自定义类或方法中虽未定义"abstract”关键字,但无需编辑即可运行。 接口 ZEND引擎2.0引入了接口。一个类可以运行任意的接口列表。 Example 例: interface Throwable { public function getMessage(); }
class Exception implements Throwable { public function getMessage() { // ... } ?> 以前代码中的用户自定义类或方法中虽未定义"interface”关键字,但无需编辑即可运行。 类类型定义 在保留类无需定义类型的同时,PHP 5引入了类类型定义来声明希望把哪个类通过参数传递给一个方法。 Example 例: interface Foo { function a(Foo $foo); }
interface Bar { function b(Bar $bar); }
class FooBar implements Foo, Bar { function a(Foo $foo) { // ... }
function b(Bar $bar) { // ... } }
$a = new FooBar; $b = new FooBar;
$a->a($b); $a->b($b); ?> 这些类类型定义在不象一些需要类型预定义的语言在编译中进行检查,而是在运行时进行。这意味着: function foo(ClassName $object) { // ... } ?> 等价于: function foo($object) { if (!($object instanceof ClassName)) { die("Argument 1 must be an instance of ClassName"); } } ?> 本语法只用于对象或类,不适用于内建类型。 final PHP 5引入了“final”关键字定义在子类中不能被覆盖的成员或方法。 例: class Foo { final function bar() { // ... } } ?> 以前代码中的用户自定义类或方法中虽未定义"final"关键字,但无需编辑即可运行。 对象克隆 PHP 4在对象被复制时,用户不能决定拷贝的机制。在复制时,PHP 4只一位一位地复制一个和原来对象一模一样的复制品。 我们并不是每次都要建立一个完全一样的复制品。一个很好的需要一种复制机制的例子是,当有一个代表一个GTK窗口的对象,它拥有该窗口的所有资源,当你建立一个拷贝时,你可能需要一个新的窗口,它拥有原窗口的所有属性,但需要拥有新窗口的资源。另外一个例子是你有一个对象引用了另外一个对象,当你复制父对象时,你希望建立那个引用对象的新实例,以使复制品引用它。 对一个对象的拷贝通过调用对象的__clone()方法完成: $copy_of_object = $object->__clone(); ?> 当开发者请求建立一个对象的新的拷贝时,ZEND引擎会检查是否定义了__clone()方法。如果未定义的话,它会调用一个默认的__clone()方法来复制该对象的所有属性。如果定义了该方法,该方法会负责在拷贝中设置必要的属性。为方便起见,引擎会提供一个函数从源对象中导入所有的属性,这上一页 [1] [2] [3] 下一页
|
|
| 网站技术录入:admin 责任编辑:admin |
|
上一篇网站技术: 第十二节 下一篇网站技术: 类的另类用法 |
| 【字体:小 大】【发表评论】【加入收藏】【告诉好友】【打印此文】【关闭窗口】 |
网友评论:(只显示最新10条。评论内容只代表网友观点,与本站立场无关!)
|
|
|
|
|