uso una trait sirve que para interfaz interfaces implementar implement classes clase abstracta php interface dynamic-languages duck-typing

php - una - trait interface



¿Hay algún punto para las interfaces en los lenguajes dinámicos? (17)

En lenguajes estáticos como Java necesita interfaces porque de lo contrario el sistema de tipos simplemente no le permitirá hacer ciertas cosas. Pero en lenguajes dinámicos como PHP y Python, solo aproveche la tipificación de pato .

PHP admite interfaces. Ruby y Python no los tienen. Entonces puedes vivir felizmente feliz sin ellos.

He estado trabajando principalmente en PHP y nunca he utilizado la capacidad de definir interfaces. Cuando necesito un conjunto de clases para implementar cierta interfaz común, entonces simplemente lo describo en la documentación.

¿Entonces, qué piensas? ¿No estás mejor sin usar interfaces en lenguajes dinámicos?


Bueno, antes que nada, es correcto que Ruby no tenga Interface como está, pero tienen mixin, lo que de alguna manera toma lo mejor de ambas interfaces y clases abstractas de otros idiomas.

El objetivo principal de la interfaz es garantizar que su objeto DEBERÁ implementar TODOS los métodos presentes en la interfaz.

Por supuesto, la interfaz nunca es obligatoria, incluso en Java podría imaginar trabajar solo con clases y usar métodos de reflexión para llamar cuando no sabe qué tipo de objeto está manipulando, pero es propenso a errores y debería desaconsejarse su uso. Muchas maneras.


Bueno, sin duda sería más fácil verificar si un objeto dado admite una interfaz completa, en lugar de no bloquearse cuando llama al uno o dos métodos que utiliza en el método inicial, por ejemplo, para agregar un objeto a una lista interna.

El tipado en pato tiene algunos de los beneficios de las interfaces, es decir, fácil de usar en todas partes, pero el mecanismo de detección todavía falta.


Creo que el uso de las interfaces está más determinado por la cantidad de personas que usarán su biblioteca. Si solo eres tú o un equipo pequeño, la documentación y la convención estarán bien y requerir interfaces será un impedimento. Si se trata de una biblioteca pública, las interfaces son mucho más útiles porque obligan a las personas a proporcionar los métodos correctos en lugar de simplemente dar pistas. Así que las interfaces son definitivamente una característica valiosa para escribir bibliotecas públicas y supongo que la falta (o al menos el énfasis) es una de las muchas razones por las que los lenguajes dinámicos se utilizan más para las aplicaciones y los idiomas fuertemente tipados para las grandes bibliotecas.


En un lenguaje como PHP donde una llamada a método que no existe produce un error fatal y toma toda la aplicación hacia abajo, entonces las interfaces sí tienen sentido.

En un lenguaje como Python donde puede detectar y manejar llamadas a métodos no válidos, no es así.


Es como decir que no necesitas tipos explícitos en un lenguaje de tipado dinámico. ¿Por qué no haces de todo un "var" y documentas sus tipos en otro lugar?

Es una restricción impuesta a un programador por un programador. Hace más difícil que te dispares en el pie; le da menos espacio para el error.


Las interfaces en realidad agregan cierto grado de flexibilidad dinámica similar a lang a los lenguajes estáticos que las tienen, como Java. Ofrecen una forma de consultar un objeto para el cual implementa contratos en tiempo de ejecución .

Ese concepto se integra bien en los lenguajes dinámicos. Dependiendo de su definición de la palabra "dinámico", por supuesto, eso incluso incluye Objective-C, que hace uso de Protocolos bastante extensamente en Cocoa.

En Ruby puede preguntar si un objeto responde a un nombre de método dado. Pero esa es una garantía bastante débil de que hará lo que usted desee, especialmente teniendo en cuenta la cantidad de palabras que se utilizan una y otra vez, que no se tenga en cuenta la firma completa del método, etc.

En Ruby podría preguntar

object.respond_to? :sync

Entonces, sí, tiene un método llamado "sincronización", sea lo que sea que eso signifique.

En Objective-C podría preguntar algo similar, es decir, "¿se ve / camina / charla como algo que se sincroniza?":

[myObject respondsToSelector:@selector(sync)]

Incluso mejor, a costa de algo de verbosidad, puedo preguntar algo más específico, es decir, "¿se ve / camina / charla como algo que se sincroniza con MobileMe?":

[myObject respondsToSelector:@selector(sync:withMobileMeAccount:)]

Eso es pato escribiendo a nivel de especie.

Pero realmente preguntarle a un objeto si está prometiendo implementar la sincronización con MobileMe ...

[receiver conformsToProtocol:@protocol(MobileMeSynchronization)]

Por supuesto, podría implementar protocolos simplemente verificando la presencia de una serie de selectores que considere la definición de un protocolo / pato, y si son lo suficientemente específicos. ¿En qué punto el protocolo es solo una abreviación de un gran grupo de respuestas feas_to? consultas, y algún azúcar sintáctico muy útil para el compilador / IDE para usar.

Las interfaces / protocolos son otra dimensión de los metadatos de objetos que se pueden usar para implementar un comportamiento dinámico en el manejo de esos objetos. En Java, el compilador simplemente exige ese tipo de cosas para la invocación de método normal. Pero incluso los lenguajes dinámicos como Ruby, Python, Perl, etc. implementan una noción de tipo que va más allá de "a qué métodos responde un objeto". De ahí la palabra clave class. Javascript es el único lenguaje realmente utilizado sin ese concepto. Si tienes clases, las interfaces también tienen sentido.

Es ciertamente más útil para bibliotecas más complicadas o jerarquías de clases que en la mayoría de los códigos de aplicaciones, pero creo que el concepto es útil en cualquier idioma.

Además, alguien más mencionó mixins. Los mixins de Ruby son una forma de compartir código, por ejemplo, se relacionan con la implementación de una clase. Las interfaces / protocolos se refieren a la interfaz de una clase u objeto. En realidad, pueden complementarse entre sí. Puede tener una interfaz que especifique un comportamiento y una o más mezclas que ayuden a un objeto a implementar ese comportamiento.

Por supuesto, no puedo pensar en ningún idioma que realmente tenga las dos características distintivas del idioma de primera clase. En aquellos con mixins, incluir el mixin generalmente implica la interfaz que implementa.


Lo pienso más como un nivel de conveniencia. Si tiene una función que toma un objeto "similar a un archivo" y solo llama a un método de lectura (), entonces es inconveniente, incluso limitante, forzar al usuario a implementar algún tipo de interfaz de archivo. Es igual de fácil comprobar si el objeto tiene un método de lectura.

Pero si su función espera un gran conjunto de métodos, es más fácil verificar si el objeto admite una interfaz y luego verificar si admite cada método en particular.



Sí, hay un punto

Si no usa interfaces explícitamente, su código aún usa el objeto como si implementara ciertos métodos, simplemente no está claro cuál es la interfaz tácita.

Si define una función para aceptar una interfaz (en PHP decir) entonces fallará antes, y el problema será con la persona que llama, no con el método haciendo el trabajo. En general, fallar antes es una buena regla general a seguir.


Si no tiene altas restricciones de seguridad (para que nadie acceda a sus datos de una manera que no desee) y tiene una buena documentación o codificadores bien capacitados (para que no necesiten el intérprete / compilador para decirles qué hacer), entonces no, es inútil.

Para la mayoría de los proyectos de tamaño mediano, todo lo que necesita es tipear patos.


Tenía la impresión de que Python no tiene interfaces . Hasta donde sé, en Python no se puede aplicar un método que se implemente en tiempo de compilación precisamente porque es un lenguaje dinámico.

Hay bibliotecas de interfaz para Python, pero no he usado ninguna de ellas.

Python también tiene Mixins por lo que podría haber creado una clase de interfaz definiendo un Mixin que tenga un pass para cada implementación de método, pero eso realmente no le está dando mucho valor.


Un uso de la "interfaz" de Java es permitir mixins fuertemente tipados en Java. Mezcla la superclase adecuada, más cualquier método adicional implementado para admitir la interfaz.

Python tiene herencia múltiple, por lo que realmente no necesita la invención de interfaz para permitir métodos de múltiples superclases.

Sin embargo, como algunos de los beneficios de la mecanografía fuerte, principalmente, soy partidario de la detección temprana de errores. Intento utilizar una definición de superclase abstracta "similar a una interfaz".

class InterfaceLikeThing( object ): def __init__( self, arg ): self.attr= None self.otherAttr= arg def aMethod( self ): raise NotImplementedError def anotherMethod( self ): return NotImplemented

Esto formaliza la interfaz, de alguna manera. No proporciona evidencia absoluta para una subclase que coincida con las expectativas. Sin embargo, si una subclase falla al implementar un método requerido, mis pruebas de unidad fallarán con un obvio valor de retorno NotImplementedError o NotImplementedError excepción NotImplementedError .


como programador de PHP, como yo lo veo, una interfaz se usa básicamente como un contrato. Le permite decir que todo lo que utiliza esta interfaz DEBE implementar un conjunto determinado de funciones.

No sé si eso es tan útil, pero encontré un poco un obstáculo para tratar de entender de qué se trataban las interfaces.


Si creía que tenía que hacerlo, podría implementar un tipo de interfaz con una función que compare los métodos / atributos de un objeto con una firma determinada. Aquí hay un ejemplo muy básico:

file_interface = (''read'', ''readline'', ''seek'') class InterfaceException(Exception): pass def implements_interface(obj, interface): d = dir(obj) for item in interface: if item not in d: raise InterfaceException("%s not implemented." % item) return True >>> import StringIO >>> s = StringIO.StringIO() >>> implements_interface(s, file_interface) True >>> >>> fp = open(''/tmp/123456.temp'', ''a'') >>> implements_interface(fp, file_interface) True >>> fp.close() >>> >>> d = {} >>> implements_interface(d, file_interface) Traceback (most recent call last): File "<stdin>", line 1, in <module> File "<stdin>", line 4, in implements_interface __main__.InterfaceException: read not implemented.

Por supuesto, eso no garantiza mucho.


Deja de intentar escribir Java en un lenguaje dinámico.


Además de las otras respuestas, solo quiero señalar que Javascript tiene una instancia de palabra clave que devolverá verdadero si la instancia dada está en alguna parte en la cadena de prototipos de un objeto dado.

Esto significa que si usa su "objeto de interfaz" en la cadena de prototipos para sus "objetos de implementación" (ambos son simplemente objetos para JS), entonces puede usar instanceof para determinar si lo "implementa". Esto no ayuda al aspecto de cumplimiento, pero sí ayuda en el aspecto de polimorfismo, que es un uso común para las interfaces.

MDN instanceof Reference


René, lea mi respuesta a la pregunta "Mejores prácticas para arquitecturas de grandes sistemas en un lenguaje dinámico" aquí en . Discuto algunos beneficios de ceder la libertad de los lenguajes dinámicos para ahorrar esfuerzo de desarrollo y facilitar la introducción de nuevos programadores al proyecto. Las interfaces, cuando se usan correctamente, contribuyen en gran medida a escribir software confiable.