doudi5291 2008-08-19 13:32
浏览 99
已采纳

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

Is there a way in PHP to overwrite a method declared by one interface in an interface extending that interface?

The Example:

I'm probably doing something wrong, but here is what I have:

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);
}

Normally in PHP, when you extend something, you can overwrite any method contained therein (right?). However, when one interface extends another, it won't let you. Unless I'm thinking about this wrong... When I implement the iShipper interface, I don't have to make the Shipper object extend the Vendor object (that implements the iVendor interface). I just say:

class FedEx implements iShipper{}

and make FedEx implement all of the methods from iVendor and iShipper. However, I need the __construct functions in iVendor and iShipper to be unique. I know I could take out the $shipment = null, but then it wouldn't be as convenient to create Shippers (by just passing in the vendors_no and the shipment while instantiating).

Anyone know how to make this work? My fallback is to have to set the shipment by calling $shipper->setShipment($shipment); on the Shipper after I instantiate it, but I'm hoping for a way to get around having to do that...

A little more explanation for the curious:
The FedEx Object has methods that go to the FedEx site (using cURL) and gets an estimate for the Shipment in question. I have a UPS Object, a BAXGlobal Object, a Conway Object, etc. Each one has COMPLETELY different methods for actually getting the shipping estimate, but all the system needs to know is that they are a "shipper" and that the methods listed in the interface are callable on them (so it can treat them all exactly the same, and loop through them in a "shippers" array calling getTransitX() to find the best shipper for a shipment).

Each "Shipper" is also a "Vendor" though, and is treated as such in other parts of the system (getting and putting in the DB, etc. Our data design is a pile of crap, so FedEx is stored right alongside companies like Dunder Mifflin in the "Vendors" table, which means it gets to have all the properties of every other Vendor, but needs the extra properties and methods supplied by iShipper).

  • 写回答

2条回答 默认 最新

  • dongxun2903 2008-08-19 14:17
    关注

    @cmcculloh Yeah, in Java you don't define constructors in Interfaces. This allows you to both extend interfaces and also have a class that implements multiple interfaces (both allowed, and very useful in many cases) without worrying about having to satisfy a particular constructor.

    EDIT:

    Here's my new model:

    A. Each interface no longer has a constructor method.
    B. All Shippers (UPS, FedEx, etc) now implement iShipper (which extends iVendor) and extend the abstract class Shipper (which has all common non-abstract methods for shippers defined in it, getName(), getZip() etc).
    C. Each Shipper has it's own unique _construct method which overwrites the abstract __construct($vendors_no = null, $shipment = null) method contained in Shipper (I don't remember why I'm allowing those to be optional now though. I'd have to go back through my documentation...).

    So:

    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...
    }
    

    Thanks for the help!
    ps. since I have now added this to "your" answer, if there is something about it you don't like/think should be different, feel free to change it...

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论
查看更多回答(1条)

报告相同问题?

悬赏问题

  • ¥15 请问有人会紧聚焦相关的matlab知识嘛?
  • ¥15 网络通信安全解决方案
  • ¥50 yalmip+Gurobi
  • ¥20 win10修改放大文本以及缩放与布局后蓝屏无法正常进入桌面
  • ¥15 itunes恢复数据最后一步发生错误
  • ¥15 关于#windows#的问题:2024年5月15日的win11更新后资源管理器没有地址栏了顶部的地址栏和文件搜索都消失了
  • ¥100 H5网页如何调用微信扫一扫功能?
  • ¥15 讲解电路图,付费求解
  • ¥15 有偿请教计算电磁学的问题涉及到空间中时域UTD和FDTD算法结合的
  • ¥15 three.js添加后处理以后模型锯齿化严重