Fare in modo che un'interfaccia sovrascriva un metodo che eredita da un'altra interfaccia in PHP

StackOverflow https://stackoverflow.com/questions/16155

  •  08-06-2019
  •  | 
  •  

Domanda

Esiste un modo in PHP per sovrascrivere un metodo dichiarato da un'interfaccia in un'interfaccia che estende quell'interfaccia?

L'esempio:

Probabilmente sto facendo qualcosa di sbagliato, ma ecco cosa ho:

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

Normalmente in PHP, quando estendi qualcosa, puoi sovrascrivere qualsiasi metodo in esso contenuto (giusto?).Tuttavia, quando un'interfaccia ne estende un'altra, non te lo consente.A meno che non ci pensi male...Quando implemento l'interfaccia iShipper, non devo fare in modo che l'oggetto Shipper estenda l'oggetto Vendor (che implementa l'interfaccia iVendor).Ho solo detto:

class FedEx implements iShipper{}

e fare in modo che FedEx implementi tutti i metodi di iVendor e iShipper.Tuttavia, ho bisogno di __construct le funzioni in iVendor e iShipper siano uniche.So che potrei eliminare il $shipment = null, ma non sarebbe altrettanto conveniente creare Shippers (semplicemente passando Vendors_no e la spedizione durante l'istanziazione).

Qualcuno sa come farlo funzionare?Il mio ripiego è dover impostare la spedizione chiamando $shipper->setShipment($shipment); sullo Shipper dopo averne creato un'istanza, ma spero in un modo per aggirare il problema di doverlo fare...

Qualche spiegazione in più per i curiosi:
L'oggetto FedEx dispone di metodi che vanno al sito FedEx (utilizzando cURL) e ottengono una stima per la spedizione in questione.Ho un oggetto UPS, un oggetto BAXGlobal, un oggetto Conway, ecc.Ognuno ha metodi COMPLETAMENTE diversi per ottenere effettivamente la stima di spedizione, ma tutto ciò che il sistema deve sapere è che si tratta di uno "spedizioniere" e che i metodi elencati nell'interfaccia possono essere richiamati su di lui (quindi può trattarli tutti esattamente allo stesso modo e scorrerli in un array "shippers" chiamando getTransitX() per trovare lo spedizioniere migliore per una spedizione).

Ogni "Mittente" è però anche un "Venditore" e viene trattato come tale in altre parti del sistema (recupero e inserimento nel DB, ecc.La progettazione dei nostri dati è un mucchio di schifezze, quindi FedEx viene archiviata accanto ad aziende come Dunder Mifflin nella tabella "Vendors", il che significa che può avere tutte le proprietà di ogni altro fornitore, ma necessita delle proprietà e dei metodi extra forniti da iShipper ).

È stato utile?

Soluzione

@cmcculloh Sì, in Java non definisci i costruttori in Interfacce.Ciò consente sia di estendere le interfacce sia di avere una classe che implementa più interfacce (entrambe consentite e molto utili in molti casi) senza preoccuparsi di dover soddisfare un particolare costruttore.

MODIFICARE:

Ecco il mio nuovo modello:

UN.Ogni interfaccia non ha più un metodo di costruzione.
B.Tutti gli spedizionieri (UPS, FedEx, ecc.) ora implementano iShipper (che estende iVendor) ed estendono la classe astratta Shipper (che ha tutti i metodi non astratti comuni per gli spedizionieri definiti al suo interno, getName(), getZip() ecc.).
C.Ogni Shipper ha il proprio metodo _construct unico che sovrascrive il metodo astratto __construct($vendors_no = null, $shipment = null) contenuto in Shipper (non ricordo perché ora permetto che siano facoltativi).Dovrei rivedere la mia documentazione...).

COSÌ:

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

Grazie per l'aiuto!
p.s.dato che ora ho aggiunto questo alla "tua" risposta, se c'è qualcosa che non ti piace/pensi che dovrebbe essere diverso, sentiti libero di cambiarlo...

Altri suggerimenti

Potresti abbandonare il costruttore e inserirli semplicemente in ogni singola classe.Quindi quello che hai è che ogni classe ha il proprio __construct, che probabilmente è lo stesso a seconda che si tratti di uno spedizioniere o di un venditore.Se vuoi che quei costrutti siano definiti solo una volta, non penso che tu voglia seguire questa strada.

Quello che penso che tu voglia fare è creare una classe astratta che implementi il ​​fornitore e una che implementi lo spedizioniere.Lì potresti definire i costruttori in modo diverso.

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

abstract class Shipper implements iShipper {
    public function __construct() {
        something();
    }
}
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top