在过去的几个月里,我在学习纯粹的oop方面取得了长足的进步,现在我正在将设计模式应用到我的工作中!所以我不得不扩展我的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,所以如果我没有正确地做这件事,请提供指导。非常感谢!
答案 0 :(得分:3)
Factory模式的唯一缺点是你可以随时绕过它 - 即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!
答案 1 :(得分:2)
如果将“新车”存储在一个数组中,您可以轻松地遍历它们并检查是否实现了给定的接口。类似的东西:
$cars['myCar'] = new HondaCivic();
$cars['myFriendCar'] = new ToyotaCorolla();
$compact_counter = 0;
foreach ($cars as $car)
if ($car instanceof CompactCar)
$compact_counter ++;
$compact_counter
将有多少小型车已经实施。
答案 2 :(得分: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这样的“鸭子类型”语言。