利用java來引入多態
買一個手電筒(說明書上寫的手電筒只能裝紅玻璃),和幾個不同顏色的玻璃片,目的是裝上不同的玻璃片,顯示不同的顏色
public class PolyTest
{
public static void main(String[] args)
{
Light light = new Light();
RedGlass rg = new RedGlass();
BlueGlass bg = new BlueGlass();
light.ons(rg);
light.ons(bg); // I want to show blue light;
}
}
class Light //手電筒
{
public void ons(RedGlass red) //對應了說明書上寫的只能裝紅玻璃
{
red.display();
}
}
class RedGlass //紅玻璃
{
public void display()
{
System.out.println("red light");
}
}
class BlueGlass //藍玻璃
{
public void display()
{
System.out.println("BlueGlass");
}
}
/**
這樣一段代碼,在java中 編譯通不過.
原因是:
public void ons(RedGlass red)
{
red.display();
}
ons方法, 指定了 接收的參數必須是 RedGlass,即紅玻璃對象
因此,你傳一個藍光玻璃,不行!
強類型語言的一個特點,
函數參數,函數的返回值,都是定死的.
改進上述java代碼
讓手電筒安裝什麼玻璃片就顯示什麼顏色
只需要讓RedGlass和BlueGlass都繼承一個父類Glass,說明書上聲明安裝玻璃Glass,不說明安裝什麼顏色的玻璃
上面程序的php實現
class Light {
// 開燈, 傳一個玻璃參數
public function ons($g) {
$g->display(); // 用玻璃渲染顏色
}
}
class RedGlass {
public function display() {
echo '紅光照耀<br />';
}
}
class BlueGlass {
public function display() {
echo '藍光照耀<br />';
}
}
class GreenGlass {
public function display() {
echo '綠光照耀<br />';
}
}
class Pig {
public function display() {
echo '八戒下凡,哼哼墜地!<br />';
}
}
// 創建一個手電筒
$light = new Light();
// 創建3塊玻璃
$red = new RedGlass();
$blue = new BlueGlass();
$green = new GreenGlass();
// 變紅燈
$light->ons($red);
// 爲藍燈
$light->ons($blue);
// 變綠燈
$light->ons($green);
// 調用錯了
$pig = new Pig();
$light->ons($pig); //任然何以運行
分析 與java那段出錯程序相比
php沒報錯,
因爲PHP是弱類型動態語言.
一個變量
$var = 8;
$var = 'hello';
$var = new Pig();
一個變量,沒有類型,你裝什麼變量都行.
同理,傳參,參數也沒有強制類型.
傳什麼參都行.
所以,對於PHP動態語言來說,豈止是多態,簡直是變態.
又有專家說, 你這個太靈活了,簡直變態,不能這麼靈活.
否則我們就不說你多態.
答:別急,我們不讓php這麼靈活還不行嗎
我對參數做類型限制總行了吧.
見下一頁
變態是因爲沒有限制類型,現在我們對參數做類型限制
限制類型的php
class Light {
// 此處,仿java,也加一個類名,做參數類型檢測
public function ons(RedGlass $g) {
// 用玻璃渲染顏色
$g->display();
}
}
class RedGlass {
public function display() {
echo '紅光照耀<br />';
}
}
class BlueGlass {
public function display() {
echo '藍光照耀<br />';
}
}
class GreenGlass {
public function display() {
echo '綠光照耀<br />';
}
}
class Pig {
public function display() {
echo '八戒下凡,哼哼墜地!<br />';
}
}
$light = new Light();// 造手電筒
$red = new RedGlass();// 造紅玻璃
$blue = new BlueGlass();// 造藍玻璃
$light->ons($red);// 紅燈亮
$light->ons($blue);// 出錯:atchable fatal error: Argument 1 passed to Light::ons() must be an instance of RedGlass, instance of BlueGlass given
說明:
加了類型檢測後,果然傳藍玻璃不行.
哲學: 子類是父類, 例:男人是人,白馬是馬,藍玻璃是玻璃.
里氏代換: 原能用父類的場合,都可以用子類來代替.
解決:參數定爲父類,傳其子類.
php實現
class Light {
// 此處,仿java,也加一個類名,做參數類型檢測
public function ons(RedGlass $g) { //只能檢測對象,這裏即使傳入int,也是按照對象看待
// 用玻璃渲染顏色
$g->display();
}
}
class Glass{
public function display(){}
}
class RedGlass extends Glass{
public function display() {
echo '紅光照耀<br />';
}
}
class BlueGlass extends Glass {
public function display() {
echo '藍光照耀<br />';
}
}
class Pig {
public function display() {
echo '八戒下凡,哼哼墜地!<br />';
}
}
$light = new Light();// 造手電筒
$red = new RedGlass();// 造紅玻璃
$blue = new BlueGlass();// 造藍玻璃
$light->ons($red);// 紅燈亮 成功
$light->ons($blue);//藍燈亮 成功
// 豬八戒降生
$pig = new Pig();
$light->ons($pig); //出錯,要的是Glass對象,傳入的卻是pig對象
說明;
如果按PHP本身特點,不檢測類型,本身就可以說是多態的,甚至變態的.
但是PHP5.3以後,引入了對於對象類型的參數檢測,
注意 只能檢測對象所屬的類
其實,這對於PHP來說,限制了其靈活性,達到的java中多態的效果.
反思多態:
其實就是
只抽象的聲明父類, 具體的工作由子類對象來完成
這樣,不同的子類對象完成,有不同的特點