Pregunta

Hay una manera en PHP para sobrescribir un método declarado por una interfaz en una interfaz de ampliación de la interfaz?

El Ejemplo:

Probablemente estoy haciendo algo mal, pero aquí es lo que tengo:

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 en PHP, al ampliar algo, puede sobrescribir cualquier método contenidas en el mismo (a la derecha?).Sin embargo, cuando una interfaz se extiende a otro, no se puede.A menos que yo estoy pensando acerca de este mal...Cuando me implementar el iShipper interfaz, no tengo que hacer el Remitente objeto de ampliar el Vendedor (objeto que implementa la interfaz de iVendor).Me acaba de decir:

class FedEx implements iShipper{}

y hacer FedEx implementar todos los métodos de iVendor y iShipper.Sin embargo, tengo la necesidad de __construct funciones en iVendor y iShipper a ser único.Sé que podría tomar el $shipment = null, pero entonces no sería conveniente crear empresas de transporte (por que acaban de pasar en el vendors_no y el envío, mientras que instanciar).

Alguien sabe cómo hacer este trabajo?Mi reserva es necesario configurar el envío llamando $shipper->setShipment($shipment); en el Cargador después de que me instancia, pero estoy esperando una manera de conseguir alrededor de tener que hacer eso...

Un poco más de explicación para los curiosos:
El FedEx Objeto tiene métodos que ir a las instalaciones de FedEx (usando cURL) y obtiene una estimación para el Envío en cuestión.Tengo un UPS Objeto, un BAXGlobal Objeto, un Conway Objeto, etc.Cada uno tiene COMPLETAMENTE diferentes métodos para conseguir la estimación del envío, pero todo el sistema necesita saber es que son una "remitente" y que los métodos que aparecen en la interfaz se puede llamar sobre ellos (para que no se las puede tratar exactamente el mismo, y el bucle a través de ellos en un "cargadores" de la matriz de llamadas getTransitX() para encontrar las mejores expedidor de un envío).

Cada "Remitente" es también un "Proveedor", sin embargo, y es tratado como tal en otras partes del sistema (obtener y poner en la base de datos, etc.Nuestro diseño de datos es un montón de mierda, así que FedEx se almacena junto con empresas como Dunder Mifflin en los "Proveedores" de la tabla, lo que significa que tiene todas las propiedades de cada Proveedor, sino que necesita de la extra de propiedades y métodos proporcionados por iShipper).

¿Fue útil?

Solución

@cmcculloh Sí, en Java no se define constructores de Interfaces.Esto le permite extender las interfaces y también tener una clase que implementa múltiples interfaces (ambos permitido, y muy útil en muchos casos) sin preocuparse de tener que satisfacer un determinado constructor.

EDITAR:

Aquí está mi nuevo modelo:

A.Cada interfaz no tiene un método constructor.
B.Todas las empresas de transporte (UPS, FedEx, etc) ahora implementar iShipper (que se extiende iVendor) y extender la clase abstracta Remitente (que tiene todos los comunes que no son métodos abstractos para los expedidores que en él se definen, getName(), getZip (), etc).
C.Cada transportista tiene su propia _construct método que sobrescribe el resumen __construct($vendors_no = null, $envío = null) método contenido en el Remitente (no recuerdo por qué estoy permitiendo que aquellos que van a ser opcional, sin embargo.Me tendría que ir de nuevo a través de mi documentación...).

Así:

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

Gracias por la ayuda!
ps.desde ahora he añadido esto a "su" respuesta, si hay algo que no te gusta/creo que debe ser diferente, siéntase libre de cambiar...

Otros consejos

Usted podría dejar el constructor y los ponen en cada clase.Entonces, lo que tienes es que cada clase tiene su propio __constructo, que probablemente es el mismo dependiendo de si se trata de un cargador o de proveedor.Si sólo quieres tener los constructos definidos por una vez no creo que quieres ir por ese camino.

Lo que creo que quieres hacer es una clase abstracta que implementa el vendedor, y uno que implementa remitente.No podría definir los constructores de manera diferente.

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

abstract class Shipper implements iShipper {
    public function __construct() {
        something();
    }
}
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top