iT邦幫忙

14

PHP物件導向的第四課:繼承

呼口號:奉行coding主義,服從pattern領導,保衛testing安全,完成project大業。
(跟神經病沒兩樣......)
今天終於要進入一個算是比較重要的物件導向議題,因為這關乎到design pattern有相當深的影響。而且在統一模塑語言(UML)中,如果單只有物件本體就根本不需要去畫UML了。(就只有屬性跟方法還要畫啥?)
我們先看一個東西:

這一張UML圖,其中上面parentCLASS代表的是父類別,而下面的childCLASS代表的是子類別。
各位會發現二個類別的方法是相同的,這是因為子類別繼承了父類別,所以會獲得父類別所有的屬性以及方法。(無括號的是屬性,有括號是方法,正常來說中間會有一條線隔開,但我cacco用不熟。另外+表示public,-表示private,#表示protected。

所謂的繼承,就是將父類別所具備的特質特性完完全全的承襲過來,程式碼的編寫如下:

class parentCLASS{
   
    public $property1 = 'property1';
    public $property2 = 'property2';

    function method1(){...}
    function method2(){...}
}

class childCLASS extends parentCLASS{

}
$child = new childCLASS();
$child->method1();
$child->method2();

上面這個程式碼就是將上方的UML圖具體呈現出來的做法。
我們可以看到childCLASS中我們並沒有寫任何的code。
但是因為他繼承了parentCLASS類別,所以他就具備了parentCLASS所有的特性。

再來一種狀況:

class parentCLASS{
   
    public $property1 = 'property1';
    public $property2 = 'property2';

    function method1(){...}
    function method2(){...}
}

class childCLASS extends parentCLASS{
    
    public $property3 = 'property3';

    function method2(){...}
  
}
$child = new childCLASS();
$child->method1();
$child->method2();

事實上繼承最主要一點是說,父類別有他本身具備的功能,子類別繼承後,除了具備父類別的功能。
同時也可以自己編寫屬於自己的功能。
這最大的一個特色在於,當別人有寫好的code時,你只需要繼承他,然後依照你自己的需求你寫你自己的功能就可以了,這在很多時候都能省下不少的時間和精力。

不過繼承上來說,有時會遇到令人尷尬的問題:

為什麼這個狀況會如此尷尬?
簡單來說,狗會跑、貓也會跑,狗會跳、貓也會跳,但是....狗叫聲總不是喵喵,貓叫聲也不是汪汪吧!

class animal{

    function run(){
        echo 'run';
    } 

    function jump(){
        echo 'jump';
    }

    function shout(){
        echo '吼~~~~~~~~~~~~~~~~~~~~~~';
    }

}

class dog extends animal{

}

class cat extends animal{

}
$dog = new dog();
$cat = new cat();
$dog->shout();
$cat->shout();

上面這狀況一整個就詭異了,狗跟貓都是用吼~~~~~~~~~~~~~~~~的!嚇死人喔!

基本上子類別雖然會繼承父類別的特性,但是繼承不一定得遵照父類別所定義的特性來做。
所以事實上就算繼承了,你還是可以去改變同名函式的內部功能。

class anumal{

    function run(){
        echo 'run';
    } 

    function jump(){
        echo 'jump';
    }

    function shout(){
        echo '吼~~~~~~~~~~~~~~~~~~~~~~';
    }

}

class dog extends animal{

    function shout(){
        echo '你吼你的我汪我的';
    }

}

class cat extends animal{

    function shout(){
        echo '你吼你的我喵我的';
    }

}
$dog = new dog();
$cat = new cat();
$dog->shout();
$cat->shout();

如此一來就可以讓子類別繼續他應有的動作不致於造成誤會。
這種改變父類別動作的方式就叫做「覆載」。

另外一種狀況來說,有時其實父類別的函式內的功能大致是對了,但是最後的結果可能和你的想法有些出來,你需要父類別的同名函式功能,又希望能寫自己的功能。就如下所示:

class animal{

    function eat(){
        echo '我要吃:';
    }

}

class dog extends animal{

    function eat(){
        parent::eat();
        echo $eat.'肉';
    }

}

你可以用parent::父類別方法()的方式來使用父類別所提供的功能。
然後在同名方法中寫入自己所要做的動作。

像上面的例子中,狗和貓雖然同屬動物,但叫聲的方式不同。
不同的形態的物件繼承同一個父類別,同樣的名稱但呈現出來的型態是不同的。
這樣的狀態就稱之為「多形」。
簡單來說假設你是男的有個妹妹,都是你爸媽生的,總不是你是男的你妹也是男的(那叫弟弟)。
在性別的形態上你們不同但都是同一個爸媽生的。

呼!今天的課程本來想繼續講委派(或說拋棄繼承),不過時間有限,就放到明天好了。

值日生記得擦黑板,倒垃圾。放學回家要乖乖的路上別亂跑。
過馬路要看紅綠燈,記得扶老太太過馬路。


0
老鷹(eagle)
iT邦高手 1 級 ‧ 2013-01-24 13:07:07

謝謝SAM大教學~~! 受益頗多~~!
謝謝謝謝
沙發沙發
筆記筆記

0
鐵殼心
iT邦高手 1 級 ‧ 2013-01-24 15:28:04

tkdmaf提到:
服從pattern領導

一時眼花看成服從phantom領導暈

phantom

戰鬥機嗎?

fillano iT邦超人 1 級‧ 2013-01-24 19:17:44 檢舉

phantom.js?

0
魯大
iT邦高手 1 級 ‧ 2013-01-24 17:00:42

tkdmaf提到:
值日生記得擦黑板,倒垃圾。放學回家要乖乖的路上別亂跑。
過馬路要看紅綠燈,記得扶老太太過馬路。

報告是!! 衝刺

看更多先前的回應...收起先前的回應...

tkdmaf提到:
記得扶老太太過馬路。

老太太不想過馬路的話要硬拉過去嗎?疑惑

魯大 iT邦高手 1 級‧ 2013-01-25 08:45:54 檢舉

先拉她過去,再扶她過馬路
XD

ted99tw iT邦高手 1 級‧ 2013-01-25 08:54:45 檢舉

為什麼要先拉後扶啊?是拉一位小姐過去,換一位阿婆回來嗎?疑惑

總裁 iT邦好手 1 級‧ 2013-01-25 09:28:16 檢舉

ted99tw提到:
拉一位小姐過去,換一位阿婆回來嗎

這可能要花點時間...冷

0
richardsuma
iT邦大師 3 級 ‧ 2013-01-24 17:28:20

謝謝解說!拍手

0
ted99tw
iT邦高手 1 級 ‧ 2013-01-24 22:48:38

tkdmaf提到:
呼口號:奉行coding主義,服從pattern領導,保衛testing安全,完成project大業。
(跟神經病沒兩樣......)

明年鐵人就是大大啦~~灑花灑花

我不要當鐵人!
我要當液態金屬人。(我看是變態嚇屬人......)

tkdmaf提到:
不要當鐵人

0
kimich7
iT邦新手 5 級 ‧ 2018-03-15 13:56:38

您好,您的這一系列的物件導向真的交的淺顯易懂,讓我獲益良多
但這篇我有一個問題不知道是不是我理解錯誤,如下所示:
class animal{.......}

class dog extends animal{......}

class cat extends cat{.....}
dog是繼承anima但是cat是繼承cat,這邊是筆誤嗎??還是真的是這樣呢??
以上謝謝您,願順心愉快

喔!對不起!那是筆誤!我改一下。

1
andrewchou
iT邦新手 5 級 ‧ 2019-01-23 16:24:37

最後一段sample code應該是

class Animal{

function eat(){
    echo '我要吃:';
}

}

class Dog extends Animal{

private $eat;

function eat(){
    $eat = parent::eat();
    echo $eat.'肉';
}

}

$dog = new Dog();
$dog->eat();

最後一段並沒有寫錯。
也不是漏掉。
而是補充,並提供大家自行發想。
表達的意思是依照自己的需求自行代換需要的code。

了解~謝謝回覆 /images/emoticon/emoticon41.gif

class dog extends animal{
    function eat(){
        parent::eat();
        echo '肉';
    }
}

這樣也可以

我要留言

立即登入留言