2

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 的所有方法。但是,我需要__constructiVendor 和 iShipper 中的功能是独一无二的。我知道我可以取出$shipment = null,但是创建 Shippers 就不那么方便了(只需在实例化时传入 vendor_no 和货件)。

任何人都知道如何使这项工作?我的后备方案是在实例化后必须通过调用$shipper->setShipment($shipment);Shipper 来设置发货,但我希望有一种方法可以绕过必须这样做......

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

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

4

2 回答 2

6

@cmcculloh是的,在Java中,您没有在接口中定义构造函数。这使您既可以扩展接口,也可以拥有一个实现多个接口的类(两者都允许,并且在许多情况下非常有用),而不必担心必须满足特定的构造函数。

编辑:

这是我的新模型:

A. 每个接口不再有构造方法。
B. 所有托运人(UPS、FedEx 等)现在都实现了 iShipper(它扩展了 iVendor)并扩展了抽象类 Shipper(其中定义了托运人的所有常见非抽象方法,getName()、getZip() 等)。
C. 每个 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...
}

谢谢您的帮助!
附言。因为我现在已将此添加到“您的”答案中,所以如果您不喜欢/认为应该有所不同,请随时更改它...

于 2008-08-19T14:17:20.923 回答
0

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

我认为您想要做的是创建一个实现供应商的抽象类,以及一个实现托运人的抽象类。在那里你可以不同地定义构造函数。

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

abstract class Shipper implements iShipper {
    public function __construct() {
        something();
    }
}
于 2008-08-19T15:31:47.390 回答