### 靜態方法(static)和屬性:通過類而不是對象來訪問數據和功能
靜態方法是以類作為作用于的函數,不能訪問這個類中的普通屬性,因為那些屬性屬于一個對象,但可以訪問靜態屬性。
如果修改了一個靜態屬性,那么這個類的所有實例都能訪問到這個新值。
例如:
~~~
print staticExample::$aNum;
StaticExample::sayHello();
~~~
要點:除非是訪問一個被覆寫的方法,負責永遠只能用::訪問被明確聲明為static的方法和屬性。
①:不能在對象中調用靜態方法
②:不能在靜態方法中使用偽變量$this
~~~
<?php
/**
* 靜態方法和屬性:通過類而不是對象來訪問數據和功能
* =============注解
* 只有使用parent關鍵字調用方法時,才能對一個非靜態方法進行靜態形式調用(一個子類可以使用parent關鍵字訪問父類,self關鍵字從當前類中訪問靜態方法或屬性)
*/
/**
* 構建shopProduct類的一個靜態方法來自動實例化shopProduct對象(在上節的shopProduct類基礎上增加)
* @return object shopProduct對象
*/
class shopProduct{
private $id=0;
//上節類中的內容
//...
public function setID($id){
$this->id=$id;
}
public static function getInstance($id, PDO $pdo){
$stmt=$pdo->prepare("select * from products where id=?");
$result=$stmt->execute(array($id));
$row=$stmt->fetch();
//實例化CD類
$product=new CDProudct($row['title'], $row['firstname'], $row['mainname'], $row['price'], $row['playlength']);
$product->setId($row['id']);
$product->setDiscount($row['dusciybt']);
return $product;
}
}
/*
* 這樣的方法有點像 工廠,可以接受原始數據或配置 據此產生對象
*/
$dsn='sqlite://home/db/bob/projects/products.db';
$pdo=new PDO($dsn, null, null);
$pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
$obj=shopProduct::getInstance(1, $pdo);
~~~
### 抽象類(abstract class)和接口(interface):設計和現實相分離
抽象類不能直接被實例化,只定義(活部分實現)子類需要的方法,子類可以繼承它并且通過實現其中的抽象方法,使抽象類具體化。
抽象類至少包含一個抽象方法
~~~
abstract class shopProductWriter{
protected $products=array();
abstract public function write();
}
~~~
~~~
<?php
/**
* 抽象類實例
* @author lxm
*/
abstract class shopProductWriter{
protected $products=array();
public function addProduct(shopProduct $shopProduct){
$this->products[]=$shopProduct;
}
abstract public function write();
}
/**
* 輸出XML
*/
class xmlProductWriter extends shopProductWriter{
public function write(){
$str='<?xml version="1.0" encoding="UTF-8"?>'."\n";
$str.="<products>\n";
foreach ($this->products as $shopProduct){
$str.="\t<product title=\"".$shopProduct->getTitle()."\">\n";
//...
}
$str.="</products>\n";
}
}
~~~
抽象類提供了具體實現的標準,而接口(interface)則是純粹的模板。接口只能定義功能,而不包含實現的內容
接口可以包含屬性和方法聲明,但是方法為空
例如:
~~~
interface Chargeable{
public function getPrice();
}
~~~
~~~
class shopProduct implements Chargeable{
//...
public function getPrice(){
return ;//...
}
}
~~~
### 攔截器方法:自動委托
PHP提供內置攔截器interceptor方法,可以 攔截 發送到未定義發放和屬性的消息。
__get($property) ? ? ? 訪問未定義的屬性時被調用
__set($property,$value) ?給未定義的屬性賦值時被調用
__isset($property) ? 對未定義的屬性調用isset()時被調用
__unset($property) 對未定義的屬性調用unset()時被調用
__call($method,$arg_array) ? 調用未定義的方法時被調用
~~~
<?php
/**
* 使用攔截器 訪問未定義屬性時,__get()被調用
* 如果不存在什么也不做,用戶試圖訪問的屬性被解析為NULL
*/
class Person{
function __get($property){
$method="get".$property;
if(!method_exists($this, $method)){
return $this->$method();
}
}
function getName(){
return "Bob";
}
function getAge(){
return 24;
}
}
$p= new Person();
print $p->name;
~~~
### 析構方法:對象銷毀前的清理工作
在對象被垃圾收集器收集前(即對象從內存中刪除之前)自動調用。
~~~
<?php
/**
* 需要把自身信息寫入數據庫,用析構方法在對象實例被刪除時確保實例把自己保存到數據庫中
*/
class Person{
private $name;
private $age;
private $id;
function __construct($name,$age){
$this->name=$name;
$this->age=$age;
}
function setID($id){
$this->id=$id;
}
function __destruct(){
if(!empty($this->id)){
//保存Person數據
print "saving person\n";
}
}
}
$person=new Person("bob", 24);
$person->setID(111);
unset($person);
//輸出
//保存Person
~~~
### 回調:用匿名函數為組件添加功能
- 前言
- PHP生成對象之設計模式—單例模式
- PHP生成對象之設計模式—工廠方法模式
- PHP之設計模式—適配器模式
- PHP之設計模式—建造者模式(通過選擇mysql,mongo數據庫鏈接類型做說明)
- PHP之設計模式—委托模式
- PHP面向對象學習一:對象基礎實踐
- PHP面向對象學習之二:深入了解面向對象高級特性
- PHP面向對象學習之三:抽象類和接口類的實際作用
- PHP解決問題進化論(整理筆記)
- PHP7新特性整理介紹篇
- php-fpm 與 Nginx優化總結
- Centos+Nginx+PHP7.0編譯安裝(和PHP5.6老版本共存)
- PHP7:Mongodb API使用
- PHP之include/require深入了解
- PHP內核了解:生命周期及運行模式