PHP之抽象類和接口

前言

對於oop,估計大多數人並不陌生。有些人除PHP外也學習不少其他語言,會發現php的不同之處,可能語法極其醜陋,但並不妨礙它成爲世界上最好的語言(邪教語言)。PHP可以允許常量作爲接口的一部分,而對於抽象的理解十分重要。
計算機上,對抽象的理解與自然語言中我們每天使用的抽象概念有所不同。比如,我們指代‘狗’、‘貓’等動物,我們會說‘那隻狗/貓’,他們就是具有狗/貓這類特徵的具體實例。但是我們不能把貓和狗看作一類,也就是說你不能說狗是貓,我們可以把狗和貓都定義到動物這一類。所以我們把抽象定義爲一個對象的基本特徵,使他與其他對象明確區分開。

抽象類

抽象類裏面可以有非抽象方法。但接口裏只能有抽象方法。 聲明方法的存在而不去實現它的類被叫做抽像類(abstract class),它用於要創建一個體現某些基本行爲的類,併爲該類聲明方法,但不能在該類中實現該類的情況。不能創建abstract 類的實例。然而可以創建一個變量,其類型是一個抽像類,並讓它指向具體子類的一個實例。不能有抽像構造函數或抽像靜態方法。Abstract 類的子類爲它們父類中的所有抽像方法提供實現,否則它們也是抽像類爲。取而代之,在子類中實現該方法。知道其行爲的其它類可以在類中實現這些方法。

先看一個普通類:

<?php
class appletree{
    privated $catch;
    piblic function tree($sweet){
        $this->catch=$sweet;
        return $this->catch;
    }
$apple=new appletree();
$eat=$apple->tree('this apple is sweet');
echo $eat;
?>

再看一個抽象類:

//appletree.php:
<?php
abstract class appletree{
    privated $catch;
    abstract public function tree1($sweet);
    public function tree2(){
        echo'smell';
    }
    public function _construct(){
        //......
        }
}
?>
<?php
include_once('appletree.php');
class anothertree extends appletree{
    public function tree1($sweet){
        $this->catch='this apple is';
        return $this->catch.$sweet;
        }
    }
$apple=new appletree();
echo $apple->tree1('sweet');
?>

從普通類和抽象類可以看出:
抽象類和抽象方法前面定義必須有abstract,調用爲extends。抽象類中可以有具體方法,並且具體方法可以在抽象類中實例化,然而抽象方法不可以在抽象類中實例化。

接口

oop模式中接口也是比不可少的一部分,接口(interface)是抽像類的變體。在接口中,所有方法都是抽像的。多繼承性可通過實現這樣的接口而獲得。接口中的所有方法都是抽像的,沒有一個有程序體。接口只可以定義static final成員變量。接口的實現與子類相似,除了該實現類不能從接口定義中繼承行爲。當類實現特殊接口時,它定義(即將程序體給予)所有這種接口的方法。然後,它可以在實現了該接口的類的任何對像上調用接口的方法。由於有抽像類,它允許使用接口名作爲引用變量的類型。通常的動態聯編將生效。引用可以轉換到接口類型或從接口類型轉換,instanceof 運算符可以用來決定某對象的類是否實現了接口。

具體例子如下:

//fruit.php
<?php
interface fruit{
    public function apple($sweet);
    public function orange();
    }
?>
<?php
include_once('fruit.php');
class fruittree implements fruit{
    privated $catch;
    public function apple($sweet){
        $this->catch='this fruit is';
        rerurn $this->catch.$sweet;
        }
    public function orange(){
        return 'this orange is sweet';
        }
    }
$tree=new fruittree();
echo $tree->apple('sweet');
echo $tree->orange();
?>

接口和常量

一個網上看到的例子:(接口名和常量之間要用間隔符‘::’隔開,接口中可以用靜態常量,變量不可以)

<?php  
interface TestInterface  
{  
    const CONSTVAR = 'aaa';  
    static staticvar = 111;  
    public function alert($str);  
}  

class TestClass implements TestInterface  
{  
    const CONSTVAR = 'bbb';  
    public function __CONSTRUCT()  
    {  
        echo TestInterface::CONSTVAR;  
    }  
    public function alert($str)  
    {  
        echo $str;  
    }  
    public function __DESTRUCT()  
    {  
    }  
}  

$test1 = new TestClass();  
?>  

我們可以看出接口和抽象類的區別:
1、接口中沒有具體方法,都是抽象方法。
2、接口調用是implements,抽象類是extends。
3、接口中不可以聲明成員變量(包括類靜態變量),但是可以聲明類常量。抽象類中可以聲明各種類型成員變量,實現數據的封裝。
4、接口沒有構造函數,抽象類可以有構造函數。
5、接口中的方法默認都是public類型的,而抽象類中的方法可以使用private,protected,public來修飾。
6、一個類可以同時實現多個接口,但一個類只能繼承於一個抽象類。

使用選擇

  1. 如果要創建一個模型,這個模型將由一些緊密相關的對象採用,就可以使用抽象類。如果要創建將由一些不相關對象採用的功能,就使用接口。

  2. 如果必須從多個來源繼承行爲,就使用接口。

  3. 如果知道所有類都會共享一個公共的行爲實現,就使用抽象類,並在其中實現該行爲。

發佈了38 篇原創文章 · 獲贊 14 · 訪問量 4萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章