类方法可能包含PHP中所谓的type hint. Type hint 是另一个传递参数给方法的类的名字. 如果你的脚本调用方法并传递一个不是类的实例的变量,PHP将产生一个”致命(fatal)错误” . 你可能没有给其它类型给出type hint,就像整型,字符串,或者布尔值. 在书写的时候, type hint是否应当包含数组类型仍存在争议.
Type hint是测试函数参数或者运算符的实例的数据类型的捷径. 你可能总是返回这个方法. 确认你强制让一个参数必须是哪种数据类型,如整型. 3.2.1 确保编译类只产生Widget的实例.
3.2.1
<?php
//组件
class Widget
{
public $name='none';
public $created=FALSE;
}
//装配器
class Assembler
{
public function make(Widget $w)
{
print("Making $w->name<br>\n");
$w->created=TRUE;
}
}
//建立一个组件对象
$thing = new Widget;
$thing->name = 'Gadget';
class Animal //动物
{
public $blood; //热血or冷血属性
public $name;
public function __construct($blood, $name=NULL)
{
$this->blood = $blood;
if($name)
{
$this->name = $name;
}
}
}
class Mammal extends Animal //哺乳动物
{
public $furColor; //皮毛颜色
public $legs;
listing 6.8 private members
<?php
class widget
{
private $name;
private $price;
private $id;
public function __construct($name, $price)
{
$this->name = $name;
$this->price = floatval($price);
$this->id = uniqid();
}
//checks if two widgets are the same 检查两个widget是否相同
public function equals($widget)
{
return(($this->name == $widget->name)and
($this->price == $widget->price));
}
}
$w1 = new widget('cog', 5.00);
$w2 = new widget('cog', 5.00);
$w3 = new widget('gear', 7.00);
//true
if($w1->equals($w2))
{
print("w1 and w2 are the same<br>n");
}
//false
if($w1->equals($w3))
{
print("w1 and w3 are the same<br>n");
}
//false, == includes id in comparison
if($w1 == $w2) //不等,因为id不同
{
print("w1 and w2 are the same<br>n");
}
?>
看例子6.10. 这段代码输出” Hey! I am Son.” 因为当PHP调用getSalutation, 是一个Son的实例,是将Father中的salutation覆写而来. 如果salutation是public的,PHP将产生相同的结果. 覆写方法的操作很类似。在Son中,对于identify的调用绑定到那个方法。
Private成员只存在于它们所在的类内部. 不像public和protected成员那样,PHP模拟静态绑定. 看例子6.11。它输出”Hello there! I am Father.”,尽管子类覆写了salutation的值,脚本将this->salutation和当前类Father绑定. 类似的原则应用于private方法identify()。
Listing 6.11 Binding and private members
class Father
{
private $salutation = "Hello there!";
public function getSalutation()
{
print("$this->salutationn");
$this->identify();
}
private function identify()
{
print("I am Father.\n");
}
}
class Son extends Father
{
private $salutation = "Hey!";
private function identify()
{
print("I am Son.\n");
}
}
$obj = new Son();
$obj->getSalutation(); //输出Hello there! I am Father.
?>
<?php
//define autoload function
function __autoload($class)
{
include("class_" . ucfirst($class) . ".php");
}
//use a class that must be autoloaded
$u = new User;
$u->name = "Leon";
$u->printName();
?>作者: tznktg 时间: 2008-6-14 11:11
第十三节 对象串行化
串行化可以把变量包括对象,转化成连续bytes数据. 你可以将串行化后的变量存在一个文件里或在网络上传输. 然后再反串行化还原为原来的数据. 你在反串行化类的对象之前定义的类,PHP可以成功地存储其对象的属性和方法. 有时你可能需要一个对象在反串行化后立即执行. 为了这样的目的,PHP会自动寻找__sleep和__wakeup方法.
//$b points to the same place in memory as $a $b与$a指向内存中同个地址
$b = &$a;
//we're changing $b, since $a is pointing to 改变$b,指向的地址改变
//the same place - it changes too $a指向的地址也改变
$b = 7;
//prints 7 输出7
print $a;
?>
由于构建一个指向彼此的对象网络是所有面向对象设计模式的基础,这个改进具有非常重大的意义.当引用允许建立更多强大的面向对象应用程序, PHP对待对象和其它类型数据相同的做法带给开发者极大的痛苦.就像任何PHP4的程序员将会告诉你的, 应用程序将会遭遇WTMA(Way Too Many Ampersands过多&)综合症. 如果你想构建一个实际应用,你会感到极为痛苦,看看例6.21你就明白.
Listing 6.21 Problems with objects in PHP 4 PHP4中使用对象的问题
class MyFoo
{
function MyFoo()
{
$this->me = &$this;
$this->value = 5;
}
function setValue($val)
{
$this->value = $val;
}
function getValue()
{
return $this->value;
}
function getValueFromMe()
{
return $this->me->value;
}
}
function CreateObject($class_type)
{
switch ($class_type)
{
case "foo":
$obj = new MyFoo();
break;
case "bar":
$obj = new MyBar();
break;
}
return $obj;
}
class MyFoo
{
function MyFoo()
{
$this->me = &$this;
$this->value = 2;
}
function setValue($val)
{
$this->value = $val;
}
function getValue()
{
return $this->value;
}
function getValueFromMe()
{
return $this->me->value;
}
}
function &CreateObject($class_type)
{
switch ($class_type)
{
case "foo":
$obj =& new MyFoo();
break;
case "bar":
$obj =& new MyBar();
break;
}
return $obj;
}