2008-08-19 17 views
2

Bu arabirimi genişleten bir arabirimde bir arabirim tarafından bildirilen bir yöntemin üzerine yazmak için PHP'de bir yol var mı?Bir arabirimin, bir arabirimin üzerine yazılması, PHP'de başka bir arabirimden devraldığı bir yöntemin üzerine yazıyor

Örnek: Bir şeyi uzatmak Normalde PHP'de

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

, sen burada yer alan herhangi bir yöntemi üzerine yazabilirsiniz: Muhtemelen burada yanlış bir şey yaptığını, ancak ediyorum

ben ne var (sağ?). Ancak, bir arayüz diğerine uzandığında, size izin vermez. Yanlış düşünmüyorsam ... iShipper arabirimini uygularken, Gönderici nesnesinin Satıcı nesnesini (iVendor arabirimini uygulayan) genişletmesini sağlamak zorunda değilim.

class FedEx implements iShipper{} 

ve FedEx iVendor ve iShipper gelen yöntemlerin hepsi uygulamak olun: Sadece söylüyorum. Bununla birlikte, iVendor ve iShipper'da benzersiz olması için __construct işlevlerine ihtiyacım var. $shipment = null'u çıkarabileceğimi biliyorum, ancak daha sonra Göndericiler oluşturmaya uygun olmayacaktı (yalnızca vendors_no'da ve gönderim sırasında gönderiyi geçerek).

Bu işi nasıl yapacağını bilen var mı? Geri dönüşümü gönderdikten sonra Gönderen üzerinde $shipper->setShipment($shipment);'u arayarak gönderiyi ayarlamak zorunda olmak zorundayım, ancak bunu yapmak için bir yol açmayı umuyoruz ki ...

Merak için biraz daha fazla açıklama :
FedEx nesnesi, FedEx sitesine (cURL kullanarak) giden ve söz konusu gönderi için bir tahminde bulunan yöntemlere sahiptir. Bir UPS Nesnesi, bir BAXGlobal Nesnesi, Conway Nesnesi, vb. Var. Her birinin nakliye tahmininin gerçekte elde edilmesi için birbirinden tamamen farklı yöntemleri vardır, ancak bilmesi gereken tüm sistem, bir "gönderici" olduğudur. Arabirim onlara yüklenebilir (bu yüzden hepsini tamamen aynı şekilde ele alabilir ve bir gönderi için en iyi nakliyeci bulmak için getTransitX() numaralı telefonu arayarak "göndericiler" dizisi içinde bunların içinden geçebilirsiniz). Her "Gönderici"

olsa da bir "Satıcı", ve sistemin diğer parçaları (alma ve DB koyarak bu şekilde muamele görür, vb veri tasarımı bok yığını FedEx, böylece olduğunu "Satıcılar" tablosunda Dunder Mifflin gibi firmaların yanında depolanır, yani diğer tüm Satıcıların tüm özelliklerine sahip olur, ancak iShipper tarafından sağlanan ekstra özelliklere ve yöntemlere ihtiyaç duyar).

+0

Nesne yönelimli PHP deneyimim sınırlıdır, ancak yapıcı tanımlarını arayüz tanımlarında gerçekten tanımlamanız gerekiyor mu? Bu genelde Java'daki uygulama değildir. –

cevap

7

@cmcculloh Evet, Java'da, Arabirimler'deki kurucuları tanımlamazsınız. Bu, hem arayüzleri genişletmenize hem de belirli bir kurucuyu tatmin etmek zorunda kalmadan endişelenmeden çoklu arayüzleri (birçok durumda izin verilen ve çok kullanışlı olan) uygulayan bir sınıfa sahip olmanızı sağlar.

DÜZENLEME:

İşte benim yeni bir model: Her arayüz artık bir yapıcı yöntemi vardır

A.. B. Tüm Taşıtanlar (UPS, FedEx, vb.) Şimdi iShipper'ı (iVendor'u genişletir) uygular ve soyut sınıf Shipper'ı (tanımlanmış taşıyıcılar için tüm soyut ve soyut olmayan yöntemleri olan getName(), getZip () vb).
C. Her bir Gönderici, Shipper'da bulunan soyut __construct ($ vendors_no = null, $ shipment = null) yönteminin üzerine yazan kendine özgü _construct yöntemine sahiptir (neden şimdi bunların isteğe bağlı olmasına izin verdiğimi hatırlamıyorum) Gerçi, dokümanlarıma geri dönmeliyim ...).

Yani: Yardım için

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

teşekkürler!
ps. Ben şimdi "sizin" cevabına ekledim, bu konuda bir şey varsa, beğenmediniz/farklı düşünmelisiniz, bunu değiştirmekten çekinmeyin ...

1

Kurucuyu bırakabilir ve sadece Her bir derse koy. Öyleyse, sahip olduğunuz her bir sınıfın kendi __construct'ı vardır, ki bu da bir gönderici veya satıcı olduğu sürece muhtemelen aynıdır. Eğer sadece bir kez tanımlanmış olan bu yapılara sahip olmak istiyorsanız, o rotayı indirmek istediğinizi düşünmüyorum.

Yapmak istediğinizi düşündüğünüz, satıcıyı uygulayan ve göndericiyi uygulayan bir soyut sınıf oluşturmak. Orada kurucuları farklı şekilde tanımlayabilirsiniz.

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

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