2

PHPで、そのインターフェイスを拡張するインターフェイスの1つのインターフェイスによって宣言されたメソッドを上書きする方法はありますか?

例:

私はおそらく何か間違ったことをしていますが、これが私が持っているものです:

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を作成するのはそれほど便利ではありません(インスタンス化中にvendors_noとshipmentを渡すだけです)。

誰かがこれを機能させる方法を知っていますか?私のフォールバックは、$shipper->setShipment($shipment);インスタンス化した後に荷送人に電話して出荷を設定する必要があることですが、それを回避する方法を望んでいます...

好奇心旺盛な方へのもう少しの説明:
FedExオブジェクトには、(cURLを使用して)FedExサイトにアクセスし、問題の貨物の見積もりを取得するメソッドがあります。UPSオブジェクト、BAXGlobalオブジェクト、Conwayオブジェクトなどがあります。それぞれに、実際に配送見積もりを取得するための完全に異なるメソッドがありますが、システムが知る必要があるのは、それらが「配送業者」であり、インターフェースはそれらで呼び出すことができます(したがって、それらをすべてまったく同じように扱い、「荷送人」配列でそれらをループしてgetTransitX()、貨物に最適な荷送人を見つけることができます)。

ただし、各「シッパー」は「ベンダー」でもあり、システムの他の部分(DBの取得と挿入など)ではそのように扱われます。データ設計はがらくたの山であるため、FedExは次のような企業と一緒に保管されます。 「ベンダー」テーブルのDunderMifflinは、他のすべてのベンダーのすべてのプロパティを取得できることを意味しますが、iShipperによって提供される追加のプロパティとメソッドが必要です。

4

2 に答える 2

6

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

于 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 に答える