一、靜態屬性和方法
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);
}
}
}