我犯了一個過錯。
沒有先講介面的話,委派的範例不是很好寫。
先來一張UML圖,這次發表文章又有點趕時間了。
所以這一課,我想還是先講介面。
在物件導向中,所謂的介面,我們可以當成是對物件的方法定義一個規範。
任何要在我們的物件所有的功能,都必須遵從介面所定義的法方去實作該方法。
即使該方法是「什麼都沒有」,你仍然要把該方法實作出來。
interface action{
public function run();
}
class animal implements action{
}
基本上,上面這一段code。
光是直接執行就會告訴你錯誤。
錯誤原因是因為你的物件要求實現action這個interface。
可是你並沒有把run()這個方法寫進你的物件。
上面有看到implements這個語法,這就是要求物件實現方法的語法。
因此我們必須做這樣的動作:
interface action{
public function run();
}
class animal implements action{
function run(){
}
}
因為你實現了這個方法,所以這段code就會通過編譯。
現在我們用之前的動物跟狗為例子。
寫了一個需要實現介面的方式。
interface action{
public function run();
public function fast();
}
class animal implements action{
function run(){
$this->fast();
}
function fast(){
}
}
class dog extends animal{
function fast(){
echo 'very fast';
}
}
$dog = new dog;
$dog->run();
這邊要注意的是說,介面基本上父類別一但實作,子類別繼承時該方法就會存在。
所以基本上父類別有寫的情形下,子類別可以不用寫,除非你想做覆載。
但是這邊就有一個問題存在了。
比如說狗跑的快,貓跑的慢一點點。
可是父類別定義的fast()卻是空的。
這表示一但狗繼承父類別,卻不設定他跑的速度的話,就無法確知狗到底是跑的快還是慢。
因此,我們或許會希望這樣。
class animal implements action{
function run(){
$this->fast();
}
}
class dog extends animal{
function fast(){
echo 'very fast';
}
}
但很不幸的,你如果這樣做。
系統會告訴你animal並未宣告fast()這個方法。
最主要是因為前面講過,一但子類別被實作,等同於父類別也被實作。
但父類別實作時卻沒有fast()這個方法。
違反了介面的使用定義。
但今天的問題是說,fast()方法應該由子類別來實作,而不是我父類別來產生。
也就是繼承體必須自行去實作fast() (而且是強迫實作,就算是空的也要寫出來)
今天既然問題出在子類別被實作(new)時,父類別也被實作的話,有沒有可能讓父類別不被實作?
有的,這個方法就是實作一個虛擬類別:
abstract class animal implements action{
function run(){
$this->fast();
}
}
上面的abstract表示宣告animal類別是一個虛擬類別。
當子類別被new的時候,animal不會被實現。
但要注意的是,通常父類別當然也可以自己被new實作出來。
但是你一但宣告abstract的話,下面這段code就一定會出錯:
abstract class animal{
}
$animal = new animal;
因為你不可以實現虛擬類別。
也因此,我們的code就會如下實現:
interface action{
public function run();
public function fast();
}
abstract class animal implements action{
function run(){
$this->fast();
}
}
class dog extends animal{
function fast(){
echo 'very fast';
}
}
$dog = new dog;
$dog->run();
因為父類別已經宣告為虛擬類別,所以不會產生實體。
但是因為子類別繼承父類別,所以連同介面都必須遵照action所定義的規範。
因此dog必須實作出fast()才行。
今天只是利用一點時間把介面先講完。
這樣才有利我接下來要講的委派 => 在物件中引用其他物件,尤其必須要遵從固定的介面。
今天沒去司法院抗議的。
請在心中支持現在抗議的民眾。
值日生記得關窗戶、關門。明天又放假了。
咦?請問版主還未繼續出嗎?感覺超級詳細的說
那個時候後來因為工作忙碌就暫時停止寫下去。
現在則是有太多東西想要講反而還沒整理好資料。
因為有不少的變革一直在持續著。
class dog extends animal{
function fast(){
echo 'very fast';
}
}
這就是可樂快跑嗎?