CoffeeScript is fantastic, the class system is really all javascript ever needed, a few keywords and a lot less proto* and braces everywhere. I've seen people implement mixins in classes, but I'm wondering if there is a path to implementing an analogy to Java interfaces?
If not it might be a good addition.. After all, it would be good to know if my code can successfully walk/quack like a duck at compile time. The following instructions might better help what would be ideal... Right now you can work around it by creating unit tests (which you should do anyway) so its not that big a deal, but still would be nice.
class definitiona
class definitionb
class featurex
class featurey
class childa extends definitiona implements featurex
class childb extends definitionb implements featurex, featurey
Generally, JavaScripters reject Java-isms like interfaces. After all, the usefulness of interfaces is that they check whether objects "quack like a duck" at compile time, and JavaScript isn't a compiled language. CoffeeScript is, but things like enforcing interfaces is far beyond its scope. A stricter compile-to-JS language like Dart might be more up your alley.
On the other hand, if you wanted to do featurex
and featurey
as mixins, that's something that's fairly common and easy to do in CoffeeScript-land. You might want to take a look at the classes chapter in The Little Book on CoffeeScript, which shows how easy it is to do this: Just define featurex
as an object whose methods you add to the prototype of childa
.
I know I'm late to the party. I won't argue the merits of why/why not to do this as it's just a tool in your developer's toolbox, but this is how I do it:
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
I have the same problem, and I've tried to solve it by adding method includes
to Function
. I described it here. This solution allows implementing multiple interfaces and provides additional method for Object
prototype that can be used instead of instanceof
operator (as we can't override any JavaScript operator).
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With