2011-03-18 71 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!