PHP對象高級特性

一、靜態屬性和方法

class StaticExample{
	static public $aNum = 0;
	static public function sayHello(){
		self::$aNum++;
		echo "hello" . self::$aNum;
	}
}
echo StaticExample::$aNum;
StaticExample::sayHello();

1、靜態方法是以類作爲作用域的函數。靜態方法不能訪問這個類的普通屬性,但可以訪問靜態屬性。

2、只有在使用parent關鍵字時。才能對一個非靜態方法進行靜態式調用。(使用::)

3、不能在對象中調用靜態方法,也不能在靜態方法中使用僞變量$this

二、常量屬性

class ConstExample{
	const A = 0;
}
$a = new ConstExample();
echo $a::A;
echo ConstExample::A;

1、常量不像常規屬性使用$開頭,一般使用大寫字母來命名常量

2、常量屬性只包含基本數據類型的值,不能將一個對象指派給常量

三、抽象類

abstract class AbstractExample{
	protected $array = array();

	public function addArray(Example $example){
		$this->array = $example;
	}

	abstract public function write();
}

1、抽象類一般都包含一個抽象方法,抽象方法用abstract關鍵字聲明,其中不能有具體內容

2、抽象類的每個子類都必須實現抽象類的所有抽象方法,或者把他們自身也聲明爲抽象方法

四、接口

interface InterfaceExample{
	public function sayHello();
}

1、接口只能定義功能,而不包含實現內容。接口可以包含屬性和方法聲明,但是方法體爲空

2、任何實現接口的類都必須實現接口中所定義的所有方法,否則該類必須聲明爲abstract

3、實現接口的類接受了它繼承的類及其實現的接口類型 如果有一個類實現了接口InterfaceExample,那麼該類的類型也屬於InterfaceExample

4、一個類可以同時繼承一個父類和實現任意個接口

五、延遲靜態綁定:static關鍵字

//實例一
abstract class DomainObject{
	public static function create(){
		return new self();
	}
}
class User extends DomainObject{}
class Document extends DomainObject{}
Document::create();
//Fatal error: Cannot instantiate abstract class DomainObject in D:\phpStudy\WWW\highLevel.php on line 89
//實例二
abstract class DomainObject{
	public static function create(){
		return new static();
	}
}
class User extends DomainObject{}
class Document extends DomainObject{}
var_dump(Document::create());
//object(Document)#2 (0) {}

/**
 * 注:
 * 1、self被解析爲定義create()的DomainObject,而不是解析爲調用self的Document類。static類似與self,但它指的是被調用的類而不是包含類
 */

//實例三
abstract class DomainObject{
	private $group;
	public function __construct(){
		$this->group = static::getGroup();
	}
	public static function create(){
		return new static();
	}
	static function getGroup(){
		return "default";
	}
}
class User extends DomainObject{}
class Document extends DomainObject{
	static function getGroup(){
		return "document";
	}
}
class SpreadSheet extends Document{}
var_dump(User::create());
var_dump(SpreadSheet::create());
//object(User)#2 (1) { ["group":"DomainObject":private]=> string(7) "default" } object(SpreadSheet)#2 (1) { ["group":"DomainObject":private]=> string(8) "document" } 

//實例四
abstract class DomainObject{
	private $group;
	public function __construct(){
		$this->group = self::getGroup();
	}
	public static function create(){
		return new static();
	}
	static function getGroup(){
		return "default";
	}
}
class User extends DomainObject{}
class Document extends DomainObject{
	static function getGroup(){
		return "document";
	}
}
class SpreadSheet extends Document{}
var_dump(User::create());
var_dump(SpreadSheet::create());
//object(User)#2 (1) { ["group":"DomainObject":private]=> string(7) "default" } object(SpreadSheet)#2 (1) { ["group":"DomainObject":private]=> string(7) "default" } 

/**
 * 注:
 * 1、static關鍵字不僅僅可以用於實例化,和self和parent一樣,static還可以作爲靜態方法調用的標誌符,甚至是從非靜態上下文調用
 */

六、Final類和方法

1、final關鍵字可以終止類的繼承,final類不能有子類,final方法不能被覆寫

七、使用攔截器

class PersonWrite{
	function writeName(Person $p){
		print $p->getName()."\n";
	}
	function writeAge(Person $p){
		print $p->getAge()."\n";
	}
}
class Person{
	private $write;
	function __construct(PersonWrite $write){
		$this->write = $write;
	}
	function __call($methodName, $arge){
		if(method_exists($this->write, $methodName)){
			return $this->write->$methodName($this);
		}
	}
	function getName(){return "Bob";}
	function getAge(){return 44;}
}
$person = new Person(new PersonWrite());
$person->writeName();
1、__get($property)                 訪問爲定義的屬性時被調用
2、__set($property, $value)         給未定義的屬性賦值時被調用
3、__isset($property)               對未定義的屬性調用isset()時被調用
4、__unset($property)               對未定義的屬性調用unset()時被調用
5、__call($method, $arg_array)      調用未定義的方法時被調用

八、析構方法

對象從內存中刪除之前自動調用,你可以利用這個方法進行最後必要的清理工作

九、使用__clone()複製對象

//PHP5以後,對象的賦值和傳遞都是通過引用進行的
//淺複製
class Account{}
class CloneExample1{
	private $account;
	function __construct(){
		$account = new Account();
	}
}
$clone1 = new CloneExample1();
$clone2 = clone $clone1;
//這樣的淺複製可以保證所有基本數據類型的豎向被完全複製。在複製對象屬性時只複製引用,並不複製引用的對象
//深複製
class Account{}
class CloneExample2{
	private $account;
	function __construct(){
		$account = new Account();
	}
	function __clone(){
		$this->account = clone $this->account;
	}
}
$clone1 = new CloneExample2();
$clone2 = clone $clone1;

十、回調、匿名函數和閉包

class Product{
	public $name;
	public $price;
	function __construct($name, $price){
		$this->name = $name;
		$this->price = $price;
	}
}
class ProcessSale{
	private $callbacks;
	function registerCallback($callback){
		if(!is_callable($callback)){
			throw new Exception("callback not callable");
		}
		$this->callbacks[] = $callback;
	}
	function sale($product){
		print "{$product->name} : processing \n";
		foreach ($this->callbacks as $callback) {
			call_user_func($callback, $product);
		}
	}
}




發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章