使一个接口覆盖它从PHP中的另一个接口继承的方法

时间:2008-08-19 13:32:12

标签: php oop interface extends

在PHP中是否有办法覆盖扩展该接口的接口中一个接口声明的方法?

示例:

我可能做错了什么,但这就是我所拥有的:

interface iVendor{
    public function __construct($vendors_no = null);
    public function getName();
    public function getVendors_no();
    public function getZip();
    public function getCountryCode();
    public function setName($name);
    public function setVendors_no($vendors_no);
    public function setZip($zip);
    public function setCountryCode($countryCode);
}

interface iShipper extends iVendor{
    public function __construct($vendors_no = null, $shipment = null);
    public function getTransitTime($shipment = null);
    public function getTransitCost($shipment = null);
    public function getCurrentShipment();
    public function setCurrentShipment($shipment);
    public function getStatus($shipment = null);
}

通常在PHP中,当你扩展某些内容时,你可以覆盖其中包含的任何方法(对吗?)。但是,当一个界面延伸到另一个界面时,它不会让你。除非我正在考虑这个错误...当我实现iShipper接口时,我不必使Shipper对象扩展Vendor对象(实现iVendor接口)。我只想说:

class FedEx implements iShipper{}

让FedEx实现iVendor和iShipper的所有方法。但是,我需要iVendor和iShipper中的__construct函数是唯一的。我知道我可以取出$shipment = null,但是创建托运人就不那么方便了(只需在实例化时传入vendors_no和货件)。

任何人都知道如何使这项工作?我的后备是必须在我实例化之后通过在托运人上调用$shipper->setShipment($shipment);来设置货件,但我希望有办法解决这个问题......

对好奇的一点解释:
FedEx对象具有进入FedEx站点的方法(使用cURL)并获得有关货件的估算。我有一个UPS对象,一个BAXGlobal对象,一个Conway对象等。每个人都有完全不同的方法来实际获得运费估算,但所有系统需要知道的是他们是“托运人”,并且列出的方法接口可以在它们上调用(因此它可以完全相同地处理它们,并在调用getTransitX()的“发货人”数组中循环它们以找到货物的最佳发货人。

虽然每个“托运人”也是“供应商”,但在系统的其他部分也是这样处理的(获取和放入数据库等等。我们的数据设计是一堆垃圾,所以联邦快递与“Dors Mifflin”等公司一起存储在“供应商”表中,这意味着它可以拥有所有其他供应商的所有属性,但需要iShipper提供的额外属性和方法。

2 个答案:

答案 0 :(得分:6)

@cmcculloh是的,在Java中,您没有在Interfaces中定义构造函数。这允许您扩展接口并且还具有实现多个接口的类(在许多情况下允许并且非常有用),而不必担心必须满足特定的构造函数。

编辑:

这是我的新模型:

甲。每个接口都不再具有构造函数方法。
B中。所有托运人(UPS,FedEx等)现在实施iShipper(扩展iVendor)并扩展抽象类Shipper(其中包含所有常见的非抽象方法,包括在其中定义的托运人,getName(),getZip()等)。
℃。每个Shipper都有自己独特的_construct方法,它覆盖了Shipper中包含的抽象__construct($ vendors_no = null,$ shipment = null)方法(我不记得为什么我现在允许这些方法是可选的。我有回顾我的文档......)。

所以:

interface iVendor{
    public function getName();
    public function getVendors_no();
    public function getZip();
    public function getCountryCode();
    public function setName($name);
    public function setVendors_no($vendors_no);
    public function setZip($zip);
    public function setCountryCode($countryCode);
}

interface iShipper extends iVendor{
    public function getTransitTime($shipment = null);
    public function getTransitCost($shipment = null);
    public function getCurrentShipment();
    public function setCurrentShipment($shipment);
    public function getStatus($shipment = null);
}

abstract class Shipper implements iShipper{  
    abstract public function __construct($vendors_no = null, $shipment = null);  
    //a bunch of non-abstract common methods...  
}

class FedEx extends Shipper implements iShipper{  
    public function __construct($vendors_no = null, $shipment = null){
        //a bunch of setup code...
    }
    //all my FedEx specific methods...
}

感谢您的帮助!
PS。因为我现在已将此添加到“你的”答案中,如果有什么关于它你不喜欢/认为应该是不同的,随时改变它...

答案 1 :(得分:0)

你可以放下构造函数,然后将它们放在每个单独的类中。那么你所拥有的是每个类都有自己的__construct,这可能是相同的,具体取决于它是托运人还是供应商。如果你只想让那些结构定义一次,我认为你不想沿着那条路走下去。

我认为你想要做的是创建一个实现供应商的抽象类,以及一个实现托运者的类。你可以用不同的方式定义构造函数。

abstract class Vendor implements iVendor {
    public function __construct() {
        whatever();
    }
}

abstract class Shipper implements iShipper {
    public function __construct() {
        something();
    }
}