2011-03-18 75 views
4

在過去的幾個月中,我學習純粹的操作系統已經走過了很長的路,現在我正在將設計模式應用到我的工作中!所以我不得不擴展我的php知識,並且我正在使用接口,擴展它們,然後實現這些接口的類。我的問題是有關從延伸另一個藉此代碼實例的接口構造類:面向對象的PHP與關鍵字接口,擴展,實現

interface Car 
{ 
    function doGeneralCarStuff(); 
    vinNumber =; 
} 

interface CompactCar extends Car 
{ 
    static $numCompactCars; 
    function doCompactCarStuff(); 
} 

class HondaCivic implements CompactCar 
{ 
    function doGeneralCarStuff() 
    { 
    //honk horn , blink blinkers, wipers on, yadda yadda 
    } 

    function doCompactCarStuff() 
    { 
     //foo and bar and foobar 
    } 

} 

class ToyotaCorolla implements CompactCar 
{ 
    function doGeneralCarStuff() 
    { 
    //honk horn , blink blinkers, wipers on, yadda yadda 
    } 

    function doCompactCarStuff() 
    { 
     //foo and bar and foobar 
    } 

} 


myCar = new HondaCivic(); 
myFriendCar = new ToyotaCorolla(); 

好了,現在可以說,我想知道的東西從我的本田延伸即CompactCar接口接口的約一。我想知道有多少小型車($ numCompactCars)已經創建。我是新來的深層(對我來說很深:p)OOP,所以如果我沒有正確地做到這一點,請提供指導。非常感謝!

回答

2

如果您將「新車」存儲在一個數組中,您可以輕鬆地遍歷它們並檢查給定接口的實現。例如:

$cars['myCar'] = new HondaCivic(); 
$cars['myFriendCar'] = new ToyotaCorolla(); 

$compact_counter = 0; 
foreach ($cars as $car) 
    if ($car instanceof CompactCar) 
    $compact_counter ++; 

$compact_counter將有多少小型車已實施。

+0

如此。但我正在嘗試使用「更多」面向對象的方法來實現它。我想從層次結構中獲取信息。不管怎麼說,還是要謝謝你! – 2011-03-18 06:04:40

+0

啊,嘗試工廠設計模式。它是一個創建其他對象的類(即$ carFactory-> createCar('HondaCivic');)。在該功能中,您可以將汽車存儲在類似上述的屬性(類變量)中,並且有一種名爲「countCompacts」的方法,該方法循環已經創建的汽車並返回總數。現在這是一個面向對象的方法。 – RDL 2011-03-18 06:12:19

+0

謝謝!我幾乎處於我書中的工廠設計模式。 – 2011-03-18 06:18:41

2

它看起來像我試圖在界面上存儲數據。這不是接口可以做的事情。接口用於描述類從外部看起來應該是什麼樣子,而不是實際實現的功能。

你想要什麼可能是一個普通的類層次結構,如:

class Car { 

    public function doGeneralCarStuff() 
    { 
     //honk horn , blink blinkers, wipers on, yadda yadda 
    } 

} 

class CompactCar extends Car { 

    public static $numCompactCars = 0; 

    public function __construct() 
    { 
     self::$numCompactCars++; 
    } 

    public function doCompactCarStuff() 
    { 
     //foo and bar and foobar 
    } 
} 

class HondaCivic extends CompactCar { 

    public function __construct() 
    { 
     parent::__construct(); 
     // do Honda Civic stuff 
    } 

} 

class ToyotaCorolla extends CompactCar 
{ 
    public function __construct() 
    { 
     parent::__construct(); 
     // do Corolla stuff 
    } 
} 

$myCar = new HondaCivic(); 
$myFriendCar = new ToyotaCorolla(); 
echo CompactCar::$numCompactCars; // -> 2 

的界面會更適合用於描述不一定遺傳特徵,如:

interface HasSunroof { 
    function openSunroof(); 
    function closeSunroof(); 
} 

在一些語言(Javascript,Ruby等)HasSunroof可能是一個「mixin」並且具有與之相關的數據和功能,但是在PHP(以及Java等)中,必須將該功能放在實現該接口的類中。

接口(根據我的經驗)在編譯時類型檢查的語言(比如Java)中比在「鴨子類型」語言(如PHP)中更常用。

+0

謝謝。當我試圖運行它時,我輸入的代碼就爆發了,所以你100%正確! – 2011-03-18 06:59:44

3

工廠模式的唯一缺點是您可以隨時繞過它 - 即new HondaCivic()會擾亂車輛數量。

這裏的東西更強大的:

<?php 

interface Car 
{ 
    function doGeneralCarStuff(); 
} 

// Declare as abstract so it can't be instantiated directly 
abstract class CompactCar 
{ 
    // Increment car count 
    function __construct() { 
     CompactCar::$numCompactCars++; 
    } 
    function __clone() { 
     CompactCar::$numCompactCars++; 
    } 
    // Decrement car count 
    function __destruct() { 
     CompactCar::$numCompactCars--; 
    } 
    // Prevent external modification of car count 
    protected static $numCompactCars; 
    // Get the current car count 
    static public function getCount() { 
     return CompactCar::$numCompactCars; 
    } 
    // Require a compact car function for descendant classes 
    abstract public function doCompactCarStuff(); 
} 

// Extend and implement 
class HondaCivic extends CompactCar implements Car 
{ 
    function doGeneralCarStuff() { } 
    function doCompactCarStuff() { } 
} 

// Extend and implement 
class ToyotaCorolla extends CompactCar implements Car 
{ 
    function doGeneralCarStuff() { } 
    function doCompactCarStuff() { } 
} 

$myCar = new HondaCivic(); // 1 car 
$myFriendCar = new ToyotaCorolla(); // 2 cars 
printf("Number of compact cars: %d\n", CompactCar::getCount()); 
$myCar = new HondaCivic(); // still only 2 cars 
unset($myFriendCar); // one car left! 
printf("Number of compact cars: %d\n", CompactCar::getCount()); 
$myCar2 = clone $myCar; // now we have two cars again 
printf("Number of compact cars: %d\n", CompactCar::getCount()); 
CompactCar::$numCompactCars = 1000; // sorry, you can't do that!