php中創建一個對象的方法
要創建一個類的實例,可以使用new關鍵字創建一個對象。
> $car = new Car(); //也可以採用變量來創建 Car爲要實例化的類名
>
> $className = 'Car';
>
> $car = new $className();
類的屬性
public:公開的
protected:受保護的
private:私有的
默認都爲public,外部可以訪問。一般通過->對象操作符來訪問對象的屬性或者方法,對於靜態屬性則使用::雙冒號進行訪問。當在類成員方法內部調用的時候,可以使用$this僞變量調用當前對象的屬性。
$car = new Car();
echo $car->name; //調用對象的屬性
echo $car->color; //錯誤 受保護的屬性不允許外部調用
echo $car->price; //錯誤 私有屬性不允許外部調用
受保護的屬性與私有屬性不允許外部調用,在類的成員方法內部是可以調用的。
class Car{
private $price = '1000';
public function getPrice() {
return $this->price; //內部訪問私有屬性
}
}
定義類的方法
訪問控制的關鍵字代表的意義爲:
public:公開的
protected:受保護的
private:私有的
我們可以這樣定義方法:
class Car {
public function getName() {
return '汽車';
}
}
$car = new Car();
echo $car->getName();
使用關鍵字static修飾的,稱之爲靜態方法,靜態方法不需要實例化對象,可以通過類名直接調用,操作符爲雙冒號::。
class Car {
public static function getName() {
return '汽車';
}
}
echo Car::getName(); //結果爲“汽車”
構造函數和析構函數
PHP5可以在類中使用__construct()定義一個構造函數,具有構造函數的類,會在每次對象創建的時候調用該函數,因此常用來在對象創建的時候進行一些初始化工作。
class Car {
function __construct() {
print "構造函數被調用\n";
}
}
$car = new Car(); //實例化的時候 會自動調用構造函數__construct,這裏會輸出一個字符串
在子類中如果定義了__construct則不會調用父類的__construct,如果需要同時調用父類的構造函數,需要使用parent::__construct()顯式的調用。
class Car {
function __construct() {
print "父類構造函數被調用\n";
}
}
class Truck extends Car {
function __construct() {
print "子類構造函數被調用\n";
parent::__construct();
}
}
$car = new Truck();
同樣,PHP5支持析構函數,使用__destruct()進行定義,析構函數指的是當某個對象的所有引用被刪除,或者對象被顯式的銷燬時會執行的函數。
class Car {
function __construct() {
print "構造函數被調用 \n";
}
function __destruct() {
print "析構函數被調用 \n";
}
}
$car = new Car(); //實例化時會調用構造函數
echo '使用後,準備銷燬car對象 \n';
unset($car); //銷燬時會調用析構函數
當PHP代碼執行完畢以後,會自動回收與銷燬對象,因此一般情況下不需要顯式的去銷燬對象。
Static靜態關鍵字
靜態屬性與方法可以在不實例化類的情況下調用,直接使用類名::方法名的方式進行調用。靜態屬性不允許對象使用->操作符調用。
class Car {
private static $speed = 10;
public static function getSpeed() {
return self::$speed;
}
}
echo Car::getSpeed(); //調用靜態方法
靜態方法也可以通過變量來進行動態調用
$func = 'getSpeed';
$className = 'Car';
echo $className::$func(); //動態調用靜態方法
靜態方法中,$this僞變量不允許使用。可以使用self,parent,static在內部調用靜態方法與屬性。
class Car {
private static $speed = 10;
public static function getSpeed() {
return self::$speed;
}
public static function speedUp() {
return self::$speed+=10;
}
}
class BigCar extends Car {
public static function start() {
parent::speedUp();
}
}
BigCar::start();
echo BigCar::getSpeed();
訪問控制
訪問控制通過關鍵字public,protected和private來實現。被定義爲公有的類成員可以在任何地方被訪問。被定義爲受保護的類成員則可以被其自身以及其子類和父類訪問。被定義爲私有的類成員則只能被其定義所在的類訪問。
類屬性必須定義爲公有、受保護、私有之一。爲兼容PHP5以前的版本,如果採用 var 定義,則被視爲公有。
class Car {
$speed = 10; //錯誤 屬性必須定義訪問控制
public $name; //定義共有屬性
}
類中的方法可以被定義爲公有、私有或受保護。如果沒有設置這些關鍵字,則該方法默認爲公有。
class Car {
//默認爲共有方法
function turnLeft() {
}
}
如果構造函數定義成了私有方法,則不允許直接實例化對象了,這時候一般通過靜態方法進行實例化,在設計模式中會經常使用這樣的方法來控制對象的創建,
比如單例模式只允許有一個全局唯一的對象。
class Car {
private function __construct() {
echo 'object create';
}
private static $_object = null;
public static function getInstance() {
if (empty(self::$_object)) {
self::$_object = new Car(); //內部方法可以調用私有方法,因此這裏可以創建對象
}
return self::$_object;
}
}
//$car = new Car(); //這裏不允許直接實例化對象
$car = Car::getInstance(); //通過靜態方法來獲得一個實例
對象繼承
繼承是面向對象程序設計中常用的一個特性,汽車是一個比較大的類,我們也可以稱之爲基類,除此之外,汽車還分爲卡車、轎車、東風、寶馬等,因爲這些子類具有很多相同的屬性和方法,可以採用繼承汽車類來共享這些屬性與方法,實現代碼的複用。
index.php
<?php
class Car {
public $speed = 0; //汽車的起始速度是0
public function speedUp() {
$this->speed += 10;
return $this->speed;
}
}
//定義繼承於Car的Truck類
class Truck extends Car {
public function speedUp() {
$this->speed = parent::speedUp() + 40;
}
}
$car = new Truck();
$car->speedUp();
echo $car->speed;
重載
PHP中的重載指的是動態的創建屬性與方法,是通過魔術方法來實現的。屬性的重載通過__set,__get,__isset,__unset來分別實現對不存在屬性的賦值、讀取、判斷屬性是否設置、銷燬屬性。
class Car {
private $ary = array();
public function __set($key, $val) {
$this->ary[$key] = $val;
}
public function __get($key) {
if (isset($this->ary[$key])) {
return $this->ary[$key];
}
return null;
}
public function __isset($key) {
if (isset($this->ary[$key])) {
return true;
}
return false;
}
public function __unset($key) {
unset($this->ary[$key]);
}
}
$car = new Car();
$car->name = '汽車'; //name屬性動態創建並賦值
echo $car->name;
方法的重載通過__call來實現,當調用不存在的方法的時候,將會轉爲參數調用__call方法,當調用不存在的靜態方法時會使用__callStatic重載。
class Car {
public $speed = 0;
public function __call($name, $args) {
if ($name == 'speedUp') {
$this->speed += 10;
}
}
}
$car = new Car();
$car->speedUp(); //調用不存在的方法會使用重載
echo $car->speed;
對象的高級特性
對象比較,當同一個類的兩個實例的所有屬性都相等時,可以使用比較運算符==進行判斷,當需要判斷兩個變量是否爲同一個對象的引用時,可以使用全等運算符===進行判斷。
class Car {
}
$a = new Car();
$b = new Car();
if ($a == $b) echo '=='; //true
if ($a === $b) echo '==='; //false
對象複製,在一些特殊情況下,可以通過關鍵字clone來複制一個對象,這時__clone方法會被調用,通過這個魔術方法來設置屬性的值。
class Car {
public $name = 'car';
public function __clone() {
$obj = new Car();
$obj->name = $this->name;
}
}
$a = new Car();
$a->name = 'new car';
$b = clone $a;
var_dump($b);
對象序列化,可以通過serialize方法將對象序列化爲字符串,用於存儲或者傳遞數據,然後在需要的時候通過unserialize將字符串反序列化成對象進行使用。
class Car {
public $name = 'car';
}
$a = new Car();
$str = serialize($a); //對象序列化成字符串
echo $str.'<br>';
$b = unserialize($str); //反序列化爲對象
var_dump($b);