类办法能够包括PHP中所谓的type hint. Type hint 是另外一个传递参数给办法的类的名字. 假如你的剧本挪用办法并传递一个不是类的实例的变量,PHP将发生一个”致命(fatal)毛病” . 你能够没有给其它类型给出type hint,就像整型,字符串,或布尔值. 在书写的时分, type hint是不是应该包括数组类型仍存在争议.
Type hint是测试函数参数或运算符的实例的数据类型的捷径. 你能够老是前往这个办法. 确认你强迫让一个参数必需是哪一种数据类型,如整型. 3.2.1 确保编译类只发生Widget的实例.
3.2.1
PHP代码:
<?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';
假如一个类从另外一类中承继而来,父类中的属性和办法将在子类中都无效,即便在子类中没有声明. 像之前提到过的,承继长短常壮大的. 假如你想会见一个承继的属性,你只需求像会见基类本人的属性那样援用便可,利用::运算符.
PHP代码:
<?php
class Room
{
public $name;
function __construct($name="unnamed")
{
$this->name = $name;
}
}
class House
{
//array of rooms
public $room;
}
//create empty house
$home = new house;
//add some rooms
$home->room[] = new Room("bedroom");
$home->room[] = new Room("kitchen");
$home->room[] = new Room("bathroom");
//show the first room of the house
print($home->room[0]->name);
?>
PHP有两个特别的定名空间arent定名空间指向父类,self定名空间指向以后的类. 例子6.6中显示了若何用parent定名空间来挪用父类中的机关函数. 同时也用self来在机关函数中挪用另外一个类办法.
<?php
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代码:
<?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");
}
?>
假如你对面向对象编程不熟习,你能够想晓得用private成员的目标是甚么. 你可以回想一下封装和耦合的设法,这在本章开首咱们有会商过. Private成员有助于封装数据. 他们可以埋没在一个类外部而不被类内部的代码接触到. 同时他们还有助于完成松懈的耦合. 假如数据布局外的代码不克不及直接会见外部属性,那末就不会发生一个隐性的联系关系性.
看例子6.10. 这段代码输入” Hey! I am Son.” 由于当PHP挪用getSalutation, 是一个Son的实例,是将Father中的salutation覆写而来. 假如salutation是public的,PHP将发生不异的了局. 覆写办法的操作很相似.在Son中,关于identify的挪用绑定到谁人办法.
Listing 6.10 Dynamic binding 静态绑定
PHP代码:
<?php
class Father
{
protected $salutation = "Hello there!"; //问候
public function getSalutation()
{
print("$this->salutation\n");
$this->identify();
}
protected function identify()
{
print("I am Father.<br>\n");
}
};
class Son extends Father
{
protected $salutation = "Hey!"; //父类中的protected $salutation 被覆写
protected function identify() //父类中的protected identify() 被覆写
{
print("I am Son.<br>\n");
}
};
$obj = new Son();
$obj->getSalutation(); //输入Hey! I am Son.
?>
//注: 在子类中没有覆写getSalutation(),但实践上依然存在一个getSalutation().这个类中的$salutation和identify()
//与Son子类的实例中的getSalutation()办法静态绑定,所以挪用Son的实例的getSalutation()办法,
//将挪用Son类中的成员salutation及identify(),而不是父类中的成员salutation及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
PHP代码:
<?php
class Father
{
private $salutation = "Hello there!";
public function getSalutation()
{
print("$this->salutation\n");
$this->identify();
}
private function identify()
{
print("I am Father.<br>\n");
}
}
class Son extends Father
{
private $salutation = "Hey!";
private function identify()
{
print("I am Son.<br>\n");
}
}
$obj = new Son();
$obj->getSalutation(); //输入Hello there! I am Father.
?>
静态绑定的优点是答应承继类来改动父类的行动,同时可以坚持父类的接口和功效. 看例子6.12. 因为利用了静态绑定,在deleteUser中被挪用的isAuthorized的version 可以由对象的类型来肯定. 假如是一个通俗的user,PHP挪用User::isAuthorized会前往FALSE.假如是一个AuthorizedUser的实例,PHP挪用AuthorizedUser::isAuthorized,将答应deleteUser顺遂履行.
Listing 6.17 Using a namespace
PHP代码:
<?php
namespace core_php:utility
{
class textEngine
{
public function uppercase($text) //大写
{
return(strtoupper($text));
}
}
//make non-OO interface 创立一个非OO的接口
function uppercase($text)
{
$e = new textEngine;
return($e->uppercase($text));
}
}
//test class in namespace 测试定名空间中的类
$e = new core_php:utility::textEngine;
print($e->uppercase("from object") . "<br>");
//test function in namespace 测试定名空间中的函数
print(core_php:utility::uppercase("from function") . "<br>");
//bring class into global namespace 把类导入全局定名空间
import class textEngine from core_php:utility;
$e2 = new textEngine;
?>
Import语句把定名空间中的某个部分导入全局的定名空间.
要导入单一的定名空间的成员,可以指定类型为constant,function或class,接着写上成员的称号;
//如import class XXX
假如你想导入某一特定类型的一切成员,你可以用*来取代称号;
//如 import constant * 导入一切常量
假如你想导入一切类型的一切成员,用*便可.
//如 import *
在成员以后,用from关头字加上定名空间的称号.
//如 import class textEngine from core_php:utility;
总之你要写成像import * from myNamespace或 import class textEngine from core_php:utility如许的语句,就像例6.17中那样.