在 PHP 中使一个接口覆盖它从另一个接口继承的方法
题
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 的所有方法。但是,我需要 __construct
iVendor 和 iShipper 中的功能是独一无二的。我知道我可以拿出 $shipment = null
, ,但是创建 Shippers 就不太方便了(只需在实例化时传入vendors_no 和发货)。
有人知道如何进行这项工作吗?我的后备措施是必须通过致电设置发货 $shipper->setShipment($shipment);
在我实例化它之后,在托运人上,但我希望有一种方法可以避免这样做......
对于好奇的人来说,还有一点解释:
FedEx 对象具有访问 FedEx 站点(使用 cURL)并获取相关货件估计值的方法。我有一个 UPS 对象、一个 BAXGlobal 对象、一个 Conway 对象等。每个人都有完全不同的方法来实际获取运费估算,但系统需要知道的是它们是“托运人”,并且接口中列出的方法可以在它们上调用(因此它可以将它们完全相同地对待) ,并在“shippers”数组中循环遍历它们,调用 getTransitX()
寻找最佳的发货人)。
不过,每个“托运人”也是一个“供应商”,并且在系统的其他部分(获取和放入数据库等)也被视为“供应商”。我们的数据设计是一堆垃圾,因此 FedEx 与 Dunder Mifflin 等公司一起存储在“供应商”表中,这意味着它可以拥有所有其他供应商的所有属性,但需要 iShipper 提供的额外属性和方法)。
解决方案
@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...
}
谢谢您的帮助!
附:因为我现在已将其添加到“您的”答案中,如果您不喜欢/认为应该有所不同,请随意更改它......
其他提示
您可以放弃构造函数并将它们放入每个单独的类中。那么你所拥有的是每个类都有自己的 __construct,这可能是相同的,具体取决于它是托运人还是供应商。如果您只想定义一次这些构造,我认为您不想走这条路。
我认为你想要做的是创建一个实现供应商的抽象类和一个实现托运人的抽象类。在那里您可以以不同的方式定义构造函数。
abstract class Vendor implements iVendor {
public function __construct() {
whatever();
}
}
abstract class Shipper implements iShipper {
public function __construct() {
something();
}
}