PHP面向对象的特有的特性

动态继承

虽然PHP对设计模式支持不够,但是,作为动态语言,PHP可以实现动态继承。而动态继承即是指子类动态选择父类。这与设计模式中的类工厂,工厂方法或抽象工厂要实现的目标是一致的。
下例即是动态继承的实现方法实例。

$databaseSystem = "mysql";
class mysql{
function show()   {
print("bar");
}
}
eval('class intermediate extends ' . $databaseSystem . ' {}');
class ActiveRecord extends intermediate{
function ActiveRecord()   {
print("foo");
}
}
$instance = new ActiveRecord;
$instance->show();

与对象相关的函数

get_class_methods — 返回由类的方法名组成的数组
get_class_vars — 返回由类的默认属性组成的数组,利用这两个函数,可以方便地为程序生成文档。
get_class — 返回对象的类名,不管是在父类中还是子类中,返回的都是当前创建的子类的类名。
get_object_vars — 返回由对象属性组成的关联数组。ORM映射时,常用此将对象转为数组。
get_parent_class — 返回对象或类的父类名
property_exists — 检查对象或类是否具有该属性,强制属性声明时,就是用的此函数。
method_exists — 检查类的方法是否存在,利用这一方法可以预留函数让用户扩展。但这一方法不太安全。即如果是非经过验证的操作,将会导致安全问题。所以,较烦琐的方法则是可以将预留的方法定义出来,让用户在扩展类扩展。

对象比较

在 PHP 中,对象比较的规则十分简单:如果两个对象的类相同,且它们有相同的属性和值,则这两个对象相等。类似的规则还适用与用全等符(===)对两个对象的比较。
这就是说,不管对象名,只要是类相同(与变量的类型相同一样),属性与值也相同(与数组比较类似),则这两个对象相等

属性(字段或称为成员变量)运行时动态添加

php对象中的属性不必显式声明,所以,可以动态添加。并且,默认情况下,不存在的属性均是Public的。所以,你大可以直接$obj->newPropertyName=$value。

方法(或称为成员函数)运行时动态添加

php5.3以前,无闭包支持,所以,只能用runkit扩展进行动态添加,而php5.3可以用闭包方式进行动态添加。

魔术函数

魔术函数是PHP对象特有的。这些函数为PHP对象提供了强大的功能。比如:
__get, __set 实现了对属性的访问控制。当需要有效性控制时,你不需要写对应的get属性名,set属性名这样的函数,只要将代码写到这两个魔术函数中即可。
__call 当方法不存在时,会调用此函数。这就给扩展提供了方便。所以,你大可以在类外面写一个函数,__call中用代码调用类外面的这个函数。从而实现了与调用类的方法相同的接口。
__isset __unset 如果你要自定义检查对象中的属性是否初始化,或释放这个属性,可以这两个方法中添加代码。
__toString  对象的toString是固有的,如果你要重载,可以在这个函数中添加代码。

软编码

php对软编码有良好的支持,特别是面向对象,类的名称,方法,属性均可以使用变量来调用。比如:

$obj=new $className()

$obj->$propertyName=true;

$result=$obj->$mothodName();

属性遍历

php帮助文档中说,要遍历属性,需要实现Iterator这个接口。实际上,这里所说的是用数据模式访问。不实现这个接口一样可以遍历。请看下面的代码,如果运行一下,你就更能明白其中的奥妙了。

class test{
public
$name,
$age,
$gender,
$education,
$hometown; 
function __construct(){} 
}
$obj=new test();
$person=array( 
'name'=>'Jhon',
'age'=>25,
'gender'=>'male',
'education'=>'master',
'hometown'=>'New York'
);
foreach($obj as $key => $value){

echo $key,'<br>';
$obj->$key=$person[$key];
}
var_dump($obj);

可以看出,最大的区别,是结果仍是对象式访问,只能用($obj->$key)而不是数组模式访问。

另外需要注意的是,只能遍历公有对象,私有的,保护的是无法遍历的。

发表评论

电子邮件地址不会被公开。 必填项已用*标注