2011-11-29 7 views
7

CoffeeScript es fantástico, el sistema de clases es realmente todo lo que JavaScript necesita, algunas palabras clave y mucho menos proto * y llaves en todas partes. He visto personas implementar mixins en las clases, pero me pregunto si existe una ruta para implementar una analogía con las interfaces de Java.CoffeeScript, implementando 'implements'

Si no, podría ser una buena adición ... Después de todo, sería bueno saber si mi código puede andar/graznar con éxito como un pato en el momento de la compilación. Las siguientes instrucciones podrían ayudar mejor a lo que sería ideal ... En este momento puedes evitarlo creando pruebas unitarias (lo cual deberías hacer de todos modos), así que no es gran cosa, pero igual sería bueno.

class definitiona 
class definitionb 

class featurex 
class featurey 

class childa extends definitiona implements featurex 
class childb extends definitionb implements featurex, featurey 

Respuesta

8

En general, los JavaScripters rechazan Java-isms como interfaces. Después de todo, la utilidad de las interfaces es que comprueban si los objetos "graznan como un pato" en tiempo de compilación, y JavaScript no es un lenguaje compilado. CoffeeScript es, pero cosas como la aplicación de interfaces está más allá de su alcance. Un lenguaje de compilación a JS más estricto como Dart podría ser más de tu estilo.

Por otro lado, si lo que quería hacer y featurexfeaturey como mixins, eso es algo que es bastante común y fácil de hacer en CoffeeScript-tierra. Es posible que desee echar un vistazo a classes chapter en The Little Book on CoffeeScript, que muestra lo fácil que es hacer esto: Simplemente defina featurex como un objeto cuyos métodos agregue al prototipo de childa.

1

Tengo el mismo problema, y ​​he intentado resolverlo agregando el método includes al Function. Lo describí here. Esta solución permite implementar múltiples interfaces y proporciona un método adicional para el prototipo Object que se puede usar en lugar del operador instanceof (ya que no podemos anular ningún operador de JavaScript).

6

Sé que llego tarde a la fiesta. No voy a discutir los méritos de qué/por qué no hacer esto ya que es sólo una herramienta en la caja de herramientas de su desarrollador, pero esto es cómo lo hago:

class.coffee

# ref - http://arcturo.github.io/library/coffeescript/03_classes.html#extending_classes 
# ref - http://coffeescriptandnodejs.blogspot.com/2012/09/interfaces-nested-classes-and.html 

# 
# @nodoc 
# 
classKeywords = ['extended', 'included', 'implements', 'constructor'] 

# 
# All framework classes should inherit from Class 
# 
class Class 

    # 
    # Utility method for implementing one of more mixin classes. 
    # 
    # @param objs [Splat] One or more mixin classes this class will *implement*. 
    # 
    @implements: (objs...) -> 
     for obj in objs 
      if typeof obj is 'function' and Boolean(obj.name) 
       obj = obj.prototype 

      for key, value of obj #when key not in moduleKeywords 
       # Assign properties to the prototype 
       if key not in classKeywords 
        #console.log 'implementing', value.toString(), 'as', key 
        @::[key] = value 

      obj.included?.apply(@) 
     this 

    # 
    # Utility method for adding getter/setters on the Class instance 
    # 
    # @param prop [String] The name of the getter/setter. 
    # @param desc [Object] The object with a getter &/or setter methods defined. 
    # 
    @property: (prop, desc)-> Object.defineProperty @prototype, prop, desc 

interface.quack.coffee

class iQuack 
    quack: -> throw new Error 'must implement interface method' 

duck.coffee

class Duck extends Class 
    @implements iQuack 

    quack: -> console.log 'quack, quack' 

https://gist.github.com/jusopi/3387db0dd25cd11d91ae