一、PHP物件導向程式設計基礎實踐
<?php
/*
* 通過物件的程式設計方式,可將實現生活中的一切事物以物件的形式表現出來。便於理解、維護、擴充套件等;
* 本示例:定義一個“人”類
* $name : 物件中的成員屬性,在此類中表示人的姓名
* say() : 物件中的成員方法,在此類中表示人說話的方法
* $this : PHP中的偽變數,表示自身的類
* __construct() : php中的魔術方法,建構函式,在例項化類時自動執行
* __destruct() : php中的魔術方法,解構函式,當類呼叫完成後自動執行
*/
class Human
{
public $name;
public $sex;
public $age;
public function __construct($name,$sex,$age)
{
$this->name = $name;
$this->sex = $sex;
$this->age = $age;
}
public function say()
{
echo `大家好,我的名字叫`.$this->name.`,今年`.$this->age.`歲,我的性別是`.$this->sex;
}
public function __destruct()
{
$this->name = null;
$this->sex = null;
$this->age = null;
}
}
//例項化“人”類
$male = new Human("張三","男","20");
//呼叫“人”類說話的方法
$male->say();
//輸出結果:大家好,我的名字叫張三,今年20歲,我的性別是男
?>
二、PHP物件導向高階程式設計實踐
知識點:類的繼承、方法重寫、訪問控制、static關鍵字、final關鍵字、資料訪問、介面、多型、抽象類
2.1、類的繼承:extends 關鍵字
例如:一員執行員、一位主持人,他們有人類共同的行為方法,但他們都有自己不同的特長專業。因此在程式設計時需要給他們建立一個父類並繼承;
<?php
/*
* 建立一個“人”類做為父類,繼承的子類都擁有其父類的成員屬性、方法
*/
class Human
{
public $name;
public function say()
{
echo "父類說話的方法,姓名:".$this->name."
";
}
public function eat()
{
echo "父類吃飯的方法
";
}
}
/*
* 建立一個“運動員”類,繼承“人”類
* extends : 關鍵字,繼承某個類
*/
class Sport extends Human
{
public $type;
public function __construct($name,$type)
{
$this->name = $name; //給父類 $name 屬性賦值
$this->type = $type;
}
public function run()
{
$this->say(); //呼叫父類“說話”的方法
echo "我在正跑步,我是一員".$this->type."運動員.....
";
}
}
/*
* 建立一個“主持人”類,繼承“人”類
* extends : 關鍵字,繼承某個類
*/
class Host extends Human
{
public $television;
public function __construct($name,$television)
{
$this->name = $name;
$this->television= $television;
}
public function perform()
{
$this->eat(); //呼叫父類“吃飯”的方法
echo "我在正表演一個節目,我是".$this->television."電視臺的一名主持人.....
";
}
}
//例項化“運動員”類
$nba = new Sport("喬丹","籃球");
$nba->run();
//例項化“主持人”類
$tv = new Host("張三","北京衛視");
$tv->perform();
//輸出結果:
//父類說話的方法,姓名:喬丹 我在正跑步,我是一員籃球運動員.....
//父類吃飯的方法 我在正表演一個節目,我是北京衛視電視臺的一名主持人.....
?>
2.2、方法重寫:子類重寫父類的方法
<?php
class Human
{
public function say()
{
echo "父類說話的方法";
}
}
class Sport extends Human
{
//重寫父類“說話”的方法
public function say()
{
echo "子類說話的方法";
}
}
$nba = new Sport();
$nba->say();
//輸出結果:子類說話的方法
?>
2.3、訪問控制:public 、 protected 、private 關鍵字
public:定義公共的成員屬性或方法,任何地方都可使用
protected : 定義受保護的成員屬性或方法,只允許類本身或子類使用
private : 定義私有的成員屬性或方法,只允許類的本身使用
<?php
class Human
{
public $name;
protected $sex;
private $age;
}
//例項化物件,給公共屬性賦值可正常輸出結果,外部不能給protected、private受保護的成員屬性賦值或使用
$worker = new Human();
$worker->name = "張三";
echo $worker->name;
?>
2.4、static(靜態)關鍵字
1)、靜態屬性用於儲存類的公有資料;
2)、靜態方法裡面只能訪問靜態屬性或方法,不能使用 $this 偽變數;
3)、靜態成員不需要通過 new 關鍵字來例項化物件就可訪問使用;
<?php
class Human
{
static $name = "張三";
static function say()
{
echo "我的姓名叫:".self::$name;
}
}
//外部使用靜態成員屬性或方法
echo Human::$name;
Human::say();
//輸出結果:張三 我的姓名叫:張三
?>
2.5、final關鍵字:不允許成員方法被重寫,不允許被繼承
例:1、對於父類“吃飯”這個方法,不希望子類重寫它;2、對於“運動員”這個類,不希望它再建立子類;
<?php
class Human
{
final public function eat()
{
echo "父類吃飯的方法,不允許子類重寫";
}
}
final class Sport extends Human
{
public function eat()
{
echo "子類吃飯的方法。此時程式將會報致命錯誤";
}
}
//建立一個類繼承 Sport 這個類。此時程式也將會報致命錯誤。因為 Sport 類不允許再建立子類
class Student extends Sport
{
public $name;
}
//例項化 Sport 類 ,呼叫 eat() 方法
$nba = new Sport();
$nba->eat();
//例項化 Student 類 ,給 name 屬性負值
$obj = new Student();
$obj->name = "張三";
//輸出結果:Fatal error: Cannot override final method Human::eat() in ******.php on line 15
//Fatal error: Class Student may not inherit from final class (Sport) in ****.php on line 20
?>
2.6、資料訪問:$this 、 self 、parent 關鍵字
$this : 偽變數,代表類的本身,可訪問本類及父類中的成員屬性與方法。
self : 訪問類中的靜態成員屬性或方法
parent :訪問父類的成員屬性或方法
<?php
class Human
{
static $name = "張三";
}
class Sport extends Human
{
static function getParentName()
{
echo parent::$name;
}
public function get()
{
self::getParentName();
}
}
$obj = new Sport();
$obj->get();
//輸出結果:張三
?>
2.7、介面:把不同類的共同行為方法進行定義,但不具體實現,由子類來實現具體的方法;
例如:人會吃飯,動物也會吃飯,甚至有些植物也會吃飯,但他們吃飯的方式不一樣,因此這時需要定義一個介面類,具體的方式由子類來實現;
定義介面關鍵字:interface
實現介面方法關鍵字:implements
<?php
//定義一個介面類,有吃飯的方法,但不具體實現。
interface ICanEat
{
public function eat($food);
}
class Human implements ICanEat
{
//eat()方法必須由子類來實現,否則程式將報致命錯誤
public function eat($food)
{
echo "I`m eating ".$food;
}
}
class Animal implements ICanEat
{
public function eat($food)
{
echo "It`s eating ".$food;
}
}
//例項化一個“人”類
$people = new Human();
$people->eat(`rice`);
//例項化一個“動物”類
$monkey = new Animal();
$monkey->eat(`banana`);
//輸出結果:I`m eating rice
// It`s eating banana
?>
2.8、多型:比如介面A有兩個實現B和C,B和C對A介面裡面定義的方法實現可以是不同的,這種現象稱之為多型;
上述例項中,ICanEat介面定義了一個eat()方法,人類吃米飯,猴子吃香蕉。他們都實現了一個“吃”的方法,但他們吃東西有不同的行為,稱之為多型;
2.9、抽象類:介入介面與類的定義之間,允許類裡面一部分方法不實現,實現一部分有相同功能且不會更改的方法。然而介面類裡面不允許有任何實現的方法。
例如:人和動物都具有吃飯與呼吸的方法,除吃飯不同以外,呼吸方法是相同的,此時需要定義一個抽象類來實現。
定義抽象類關鍵字:abstract
<?php
//定義一個抽象類,裡面有吃飯和呼吸的方法。呼吸方法需要在抽象類中具體實現
abstract class ICanEat
{
abstract function eat($food);
public function breath()
{
echo `Breath use the air...`;
}
}
class Human extends ICanEat
{
public function eat($food)
{
echo "I`m eating ".$food;
$this->breath();
}
}
//例項化“人”類
$people = new Human();
$people->eat(`rice`);
//輸出結果:I`m eating rice Breath use the air...
?>
三、PHP物件導向程式設計特殊實踐
PHP語言特定的一些魔術方法:
<?php
class Object
{
public function __construct()
{
echo "當類在被例項化的時候,自動執行該函式";
}
public function __toString()
{
return "當物件被當作字串形式輸出時,自動執行該函式";
}
public function __invoke($value)
{
echo "當物件被當作函式呼叫時,自動執行該函式".$value;
}
/*
* 當物件訪問不存在的方法時,自動執行該函式。也稱之為“方法過載”
* $fun : 方法名稱
* $param : 傳遞的引數
*/
public function __call($fun,$param)
{
echo "呼叫".$fun."方法不存在,傳遞的引數".implode(`,`,$param);
}
/*
* 當物件訪問不存在的靜態方法時,自動執行該函式。
* $fun : 方法名稱
* $param : 傳遞的引數
*/
static function __callStatic($fun,$param)
{
echo "呼叫".$fun."靜態方法不存在,傳遞的引數".implode(`,`,$param);
}
public function __get($key)
{
echo "當讀取物件中不可訪問(未定義)的屬性值時,自動呼叫該函式。".$key."屬性不可訪問或未定義";
}
public function __set($key,$value)
{
echo "當給物件中不可訪問(未定義)的屬性賦值時,自動呼叫該函式。".$key."屬性不可訪問或未定義,值".$value;
}
public function __isset($key)
{
echo "判斷物件中的屬性不存在時,自動執行該函式。屬性:".$key."值未定義";
}
public function __unset($key)
{
echo "釋放物件中的不存在的屬性值時,自動執行該函式。屬性:".$key."值未定義";
}
public function __clone()
{
echo "當物件被克隆時,自動執行該函式。";
}
public function __destruct()
{
echo "當物件執行完成後,自動執行該函式";
}
}
$obj = new Object(); //例項化物件時,呼叫__construct()方法
echo $obj; //將物件以字串形式輸出時,呼叫__toString()方法
$obj(123); //當物件以函式形式呼叫時,執行__invoke()方法
$obj->runTest(); //當呼叫物件中不存在的方法時,執行__call()方法
$obj::runTest(); //當呼叫物件中不存在的靜態方法時,執行__callStatic()方法
$obj->name; //當呼叫物件中不存在的成員屬性時,執行__get()方法
$obj->name = "張三"; //當給物件中不存在的成員屬性賦值時,執行__set()方法
isset($obj->name) ? 1 : 0; //判斷物件中不存在的成員屬性時,執行__isset()方法
unset($obj->name); //釋放物件中的不存在的屬性值時,執行__unset()方法
$obj2 = clone $obj; //當物件被克隆時,執行__clone()方法
//物件執行完畢,執行__destruct()方法
?>