欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

PHP 面向?qū)ο蟪绦蛟O(shè)計(jì)(oop)學(xué)習(xí)筆記(一) - 抽象類(lèi)、對(duì)象接口、instanceof 和契約式編程

 更新時(shí)間:2014年06月12日 09:48:28   投稿:hebedich  
面向?qū)ο蟪绦蛟O(shè)計(jì)(OOP)是一種計(jì)算機(jī)編程架構(gòu)。OOP的一條基本原則是計(jì)算機(jī)程序是由單個(gè)能夠起到子程序作用的單元或?qū)ο蠼M合而成。OOP達(dá)到了軟件工程的三個(gè)主要目標(biāo):重用性、靈活性和擴(kuò)展性。為了實(shí)現(xiàn)整體運(yùn)算,每個(gè)對(duì)象都能夠接收信息、處理數(shù)據(jù)和向其它對(duì)象發(fā)送信息。

1、PHP中的抽象類(lèi)

PHP 5 支持抽象類(lèi)和抽象方法。定義為抽象的類(lèi)不能被實(shí)例化。任何一個(gè)類(lèi),如果它里面至少有一個(gè)方法是被聲明為抽象的,那么這個(gè)類(lèi)就必須被聲明為抽象的。被定義為抽象的方法只是聲明了其調(diào)用方式(參數(shù)),不能定義其具體的功能實(shí)現(xiàn)。在類(lèi)的聲明中使用 abstract 修飾符可以將某個(gè)類(lèi)聲明為抽象的。

可以這樣理解,抽象類(lèi)作為一個(gè)基類(lèi),它把特定的細(xì)節(jié)留給繼承者來(lái)實(shí)現(xiàn)。通過(guò)抽象概念,可以在開(kāi)發(fā)項(xiàng)目中創(chuàng)建擴(kuò)展性很好的架構(gòu)。

復(fù)制代碼 代碼如下:

abstract class AbstractClass
{
    code...
}

1.1、抽象方法

使用 abstract 關(guān)鍵字定義抽象方法。抽象方法只保留方法原型(方法的定義中剔除了方法體之后的簽名),它包括存取級(jí)別、函數(shù)關(guān)鍵字、函數(shù)名稱(chēng)和參數(shù)。他不包含({})或者括號(hào)內(nèi)部的任何代碼。例如下面的代碼就是一個(gè)抽象方法定義:

復(fù)制代碼 代碼如下:

abstract public function prototypeName($protoParam);

繼承一個(gè)抽象類(lèi)的時(shí)候,子類(lèi)必須定義父類(lèi)中的所有抽象方法;另外,這些方法的訪問(wèn)控制必須和父類(lèi)中一樣(或者更為寬松)。此外方法的調(diào)用方式必須匹配,即類(lèi)型和所需參數(shù)數(shù)量必須一致。

1.2、關(guān)于抽象類(lèi)

某個(gè)類(lèi)只要包含至少一個(gè)抽象方法就必須聲明為抽象類(lèi)
聲明為抽象的方法,在實(shí)現(xiàn)的時(shí)候必須包含相同的或者更低的訪問(wèn)級(jí)別。
不能使用 new 關(guān)鍵字創(chuàng)建抽象類(lèi)的實(shí)例。
被聲明為抽象的方法不能包含函數(shù)體。
如果將擴(kuò)展的類(lèi)也聲明為抽象類(lèi),在擴(kuò)展抽象類(lèi)時(shí),可以不用實(shí)現(xiàn)所有的抽象方法。(如果某個(gè)類(lèi)從抽象類(lèi)繼承,當(dāng)它沒(méi)有實(shí)現(xiàn)基類(lèi)中所聲明的所有抽象方法時(shí),它就必須也被聲明為抽象的。)
1.3、使用抽象類(lèi)

復(fù)制代碼 代碼如下:

<?php
abstract class Car
{   
    abstract function getMaxSpeend();
}
class Roadster extends Car
{
    public $Speend;
    public function SetSpeend($speend = 0)
    {
        $this->Speend = $speend;
    }
    public function getMaxSpeend()
    {
        return $this->Speend;
    }
}
class Street
{
    public $Cars ;
    public $SpeendLimit ;
    function __construct( $speendLimit = 200)
    {
        $this -> SpeendLimit = $speendLimit;
        $this -> Cars = array();
    }
    protected function IsStreetLegal($car)
    {
        if ($car->getMaxSpeend() < $this -> SpeendLimit)
        {
            return true;
        }
        else
        {
            return false;
        }
    }
    public function AddCar($car)
    {
        if($this->IsStreetLegal($car))
        {
            echo 'The Car was allowed on the road.';
            $this->Cars[] = $car;
        }
        else
        {
            echo 'The Car is too fast and was not allowed on the road.';
        }
    }
}
$Porsche911 = new Roadster();
$Porsche911->SetSpeend(340);
$FuWaiStreet = new Street(80);
$FuWaiStreet->AddCar($Porsche911);
/**
 *
 * @result
 *
 * The Car is too fast and was not allowed on the road.[Finished in 0.1s]
 *
 */
?>


2.對(duì)象接口

使用接口(interface),可以指定某個(gè)類(lèi)必須實(shí)現(xiàn)哪些方法,但不需要定義這些方法的具體內(nèi)容。

接口是通過(guò) interface 關(guān)鍵字來(lái)定義的,就像定義一個(gè)標(biāo)準(zhǔn)的類(lèi)一樣,但其中定義所有的方法都是空的。

接口中定義的所有方法都必須是公有,這是接口的特性。

接口是一種類(lèi)似于類(lèi)的結(jié)構(gòu),可用于聲明實(shí)現(xiàn)類(lèi)所必須聲明的方法。例如,接口通常用來(lái)聲明API,而不用定義如何實(shí)現(xiàn)這個(gè)API。

大多數(shù)開(kāi)發(fā)人員選擇在接口名稱(chēng)前加上大寫(xiě)字母I作為前綴,以便在代碼和生成的文檔中將其與類(lèi)區(qū)別開(kāi)來(lái)。

2.1接口實(shí)現(xiàn)(implements)

要實(shí)現(xiàn)一個(gè)接口,使用 implements 操作符(繼承抽象類(lèi)需要使用 extends 關(guān)鍵字不同),類(lèi)中必須實(shí)現(xiàn)接口中定義的所有方法,否則會(huì)報(bào)一個(gè)致命錯(cuò)誤。類(lèi)可以實(shí)現(xiàn)多個(gè)接口,用逗號(hào)來(lái)分隔多個(gè)接口的名稱(chēng)。

實(shí)現(xiàn)多個(gè)接口時(shí),接口中的方法不能有重名。
接口也可以繼承,通過(guò)使用 extends 操作符。
類(lèi)要實(shí)現(xiàn)接口,必須使用和接口中所定義的方法完全一致的方式。否則會(huì)導(dǎo)致致命錯(cuò)誤。
接口中也可以定義常量。接口常量和類(lèi)常量的使用完全相同,但是不能被子類(lèi)或子接口所覆蓋。
2.2使用接口的案例

復(fù)制代碼 代碼如下:

<?php
abstract class Car
{   
    abstract function SetSpeend($speend = 0);
}
interface ISpeendInfo
{
    function GetMaxSpeend();
}
class Roadster extends Car implements ISpeendInfo
{
    public $Speend;
    public function SetSpeend($speend = 0)
    {
        $this->Speend = $speend;
    }
    public function getMaxSpeend()
    {
        return $this->Speend;
    }
}
class Street
{
    public $Cars ;
    public $SpeendLimit ;
    function __construct( $speendLimit = 200)
    {
        $this -> SpeendLimit = $speendLimit;
        $this -> Cars = array();
    }
    protected function IsStreetLegal($car)
    {
        if ($car->getMaxSpeend() < $this -> SpeendLimit)
        {
            return true;
        }
        else
        {
            return false;
        }
    }
    public function AddCar($car)
    {
        if($this->IsStreetLegal($car))
        {
            echo 'The Car was allowed on the road.';
            $this->Cars[] = $car;
        }
        else
        {
            echo 'The Car is too fast and was not allowed on the road.';
        }
    }
}

$Porsche911 = new Roadster();
$Porsche911->SetSpeend(340);
$FuWaiStreet = new Street(80);
$FuWaiStreet->AddCar($Porsche911);
/**
 *
 * @result
 *
 * The Car is too fast and was not allowed on the road.[Finished in 0.1s]
 *
 */
?>

3、類(lèi)型運(yùn)算符 instanceof

instanceof 運(yùn)算符是 PHP5 中的一個(gè)比較操作符。他接受左右兩邊的參數(shù),并返回一個(gè)boolean值。

確定一個(gè) PHP 變量是否屬于某個(gè)一類(lèi) CLASS 的實(shí)例
檢查對(duì)象是不是從某個(gè)類(lèi)型繼承
檢查對(duì)象是否屬于某個(gè)類(lèi)的實(shí)例
確定一個(gè)變量是不是實(shí)現(xiàn)了某個(gè)接口的對(duì)象的實(shí)例

復(fù)制代碼 代碼如下:

echo $Porsche911 instanceof Car;
//result:1

echo $Porsche911 instanceof ISpeendInfo;
//result:1

4.契約式編程

契約式設(shè)計(jì)或者Design by Contract (DbC)是一種設(shè)計(jì)計(jì)算機(jī)軟件的方法。這種方法要求軟件設(shè)計(jì)者為軟件組件定義正式的,精確的并且可驗(yàn)證的接口,這樣,為傳統(tǒng)的抽象數(shù)據(jù)類(lèi)型又增加了先驗(yàn)條件、后驗(yàn)條件和不變式。這種方法的名字里用到的“契約”或者說(shuō)“契約”是一種比喻,因?yàn)樗蜕虡I(yè)契約的情況有點(diǎn)類(lèi)似。

在編寫(xiě)類(lèi)之前實(shí)現(xiàn)聲明接口的一種編程實(shí)踐。這種方法在保證類(lèi)的封裝性方面非常有用。使用契約式編程技術(shù),我們可以在創(chuàng)建應(yīng)用程序之前定義出視圖實(shí)現(xiàn)的功能,這和建筑師在修建大樓之前先畫(huà)好藍(lán)圖的做法非常相似。

5.總結(jié)

抽象類(lèi)是使用 abstract 關(guān)鍵字聲明的類(lèi)。通過(guò)將某個(gè)類(lèi)標(biāo)記為抽象類(lèi),我們可以推遲實(shí)現(xiàn)所聲明的方法。要將某個(gè)方法聲明為抽象方法,只要去掉包含所有大括號(hào)的方法實(shí)體,將方法聲明的代碼行用分號(hào)結(jié)束即可。

抽象類(lèi)不能直接實(shí)例化,他們必須被繼承。

如果某個(gè)類(lèi)從抽象類(lèi)繼承,當(dāng)它沒(méi)有實(shí)現(xiàn)基類(lèi)中所聲明的所有抽象方法時(shí),它就必須也被聲明為抽象的。

在接口中,我們可以聲明沒(méi)有方法體的方法原型,這點(diǎn)與抽象類(lèi)很相似。他們之間的區(qū)別在于,接口不能聲明任何具有方法體的方法;并且他們使用的語(yǔ)法也不一樣。為了將揭開(kāi)規(guī)則強(qiáng)制加到某個(gè)類(lèi)上,我們需要使用implements關(guān)鍵字,而不是extends關(guān)鍵字。

有些情況下我們需要確定某個(gè)類(lèi)是否是特定類(lèi)的類(lèi)型,或者是否實(shí)現(xiàn)了特定的接口。 instanceof 分成適合完成這個(gè)任務(wù)。instanceof 檢查三件事情:實(shí)例是否是某個(gè)特定的類(lèi)型,實(shí)例是否從某個(gè)特定的類(lèi)型繼承,實(shí)例或者他的任何祖先類(lèi)是否實(shí)現(xiàn)類(lèi)特定的接口。

某些語(yǔ)言具有從多個(gè)類(lèi)繼承的能力,這稱(chēng)為多重繼承。PHP不支持多重繼承。想法,他提供了為一個(gè)類(lèi)聲明多個(gè)接口的功能。

接口在聲明類(lèi)必須遵循的規(guī)則時(shí)非常有用。契約式編程技術(shù)使用這一功能來(lái)增強(qiáng)封裝性,優(yōu)化工作流。

相關(guān)文章

  • thinkphp5框架路由原理與用法詳解

    thinkphp5框架路由原理與用法詳解

    這篇文章主要介紹了thinkphp5框架路由原理與用法,結(jié)合圖文與實(shí)例形式詳細(xì)分析了thinkPHP5框架路由的相關(guān)原理、使用方法及操作注意事項(xiàng),需要的朋友可以參考下
    2020-02-02
  • Laravel學(xué)習(xí)教程之本地化模塊

    Laravel學(xué)習(xí)教程之本地化模塊

    這篇文章主要給大家介紹了關(guān)于Laravel學(xué)習(xí)教程之本地化模塊的相關(guān)資料,文中通過(guò)示例代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面跟著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧。
    2017-08-08
  • YII2框架中actions的作用與使用方法示例

    YII2框架中actions的作用與使用方法示例

    這篇文章主要介紹了YII2框架中actions的作用與使用方法,結(jié)合實(shí)例形式分析了YII2中actions功能、原理、使用方法及操作注意事項(xiàng),需要的朋友可以參考下
    2020-03-03
  • 基于php設(shè)計(jì)模式中單例模式的應(yīng)用分析

    基于php設(shè)計(jì)模式中單例模式的應(yīng)用分析

    本篇文章是對(duì)php設(shè)計(jì)模式中單例模式的應(yīng)用進(jìn)行了詳細(xì)的分析介紹,需要的朋友參考下
    2013-05-05
  • Laravel學(xué)習(xí)筆記之Artisan命令生成自定義模板的方法

    Laravel學(xué)習(xí)筆記之Artisan命令生成自定義模板的方法

    這篇文章主要介紹了Laravel學(xué)習(xí)筆記之Artisan命令生成自定義模板的方法,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧
    2018-11-11
  • CI分頁(yè)類(lèi)首頁(yè)、尾頁(yè)不顯示的解決方法

    CI分頁(yè)類(lèi)首頁(yè)、尾頁(yè)不顯示的解決方法

    這篇文章主要介紹了CI分頁(yè)類(lèi)首頁(yè)、尾頁(yè)不顯示的解決方法,結(jié)合實(shí)例形式較為詳細(xì)的分析說(shuō)明了CI框架分頁(yè)代碼的運(yùn)行原理與顯示首頁(yè)、尾頁(yè)的具體方法,需要的朋友可以參考下
    2016-03-03
  • PHP驗(yàn)證碼語(yǔ)言包預(yù)警信息通知總結(jié)示例

    PHP驗(yàn)證碼語(yǔ)言包預(yù)警信息通知總結(jié)示例

    這篇文章主要為大家介紹了PHP驗(yàn)證碼語(yǔ)言包預(yù)警信息通知總結(jié)示例,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2023-08-08
  • thinkPHP3.2使用RBAC實(shí)現(xiàn)權(quán)限管理的實(shí)現(xiàn)

    thinkPHP3.2使用RBAC實(shí)現(xiàn)權(quán)限管理的實(shí)現(xiàn)

    這篇文章主要介紹了thinkPHP3.2使用RBAC實(shí)現(xiàn)權(quán)限管理的實(shí)現(xiàn),文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2019-08-08
  • laravel實(shí)現(xiàn)前后臺(tái)路由分離的方法

    laravel實(shí)現(xiàn)前后臺(tái)路由分離的方法

    今天小編就為大家分享一篇laravel實(shí)現(xiàn)前后臺(tái)路由分離的方法,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧
    2019-10-10
  • 在php的yii2框架中整合hbase庫(kù)的方法

    在php的yii2框架中整合hbase庫(kù)的方法

    這篇文章主要介紹了在php的yii2框架中整合hbase庫(kù)的方法,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧
    2018-09-09

最新評(píng)論