We have used a homegrown version of object oriented coldfusion for a while and I'm just starting to experiment with cfc's and how it "should" be done...
If I understand correctly, cfinterface defines the signature of functions, and any class that implements that interface must have their own functions to do whats defined in the interface.
I'm kind of trying to do the opposite - the interface doesn't just define the function's signature, but also defines the logic of the function and anything that implements that interface can use its functions without having to define it itself. Does that exist besides creating subclasses?
For example, say you have classes A,B,C,D that all belong to the Animal class
- A & B can walk
- A & C can talk
- B & D can sleep
- Suppose the logic of walk, talk & sleep (if the object can do it) is the same regardless of the class doing it
- Ideally, if A & B both implement the walking interface, they can walk without defining a separate walk method in each class.
Or borrowing a better example from this java multiple inheritance question
- A Pegasus is a mix of a Horse and a Bird because it runs like a horse
but flies like a bird
Is that possible? (I think this is multiple inheritance?)
In short: no, an interface only defines a contract, it does not (and cannot) define functionality). Also CFML does not have the concept of multiple inheritance.
You will have to use single-inheritance and concrete implementations to effect what you need. I can't be bothered assessing your implementation-sharing requirements to work out what an approrpriate class hierarchy might be to minimise code duplication. I'm sure you can do that yourself (and it's not really part of your question anyhow).
One tactic you could try is to use mixins for your common methods. Store the common methods in a different library, and then inject them into your objects as required. So basically Mixins.cfc would implement walk()
, talk()
, sleep()
, and you'd have an AFactory.cfc
, BFactory.cfc
, CFactory.cfc
. When asking a factory for a new A
, B
or C
, and the factory method injects the mixin methods before returning the instances. Obviously this is a fairly cumbersome process, and you'd want to use some sort of IoC container to manage all this.
A better question might come out of you showing us more real world examples... I suspect your domain design could perhaps stand improvement if you find yourself needing to do what your example suggests. Actual design requirements are seldom exposed with examples using animals.
You can do similar things with WireBox and its Virtual Inheritance feature:
http://wiki.coldbox.org/wiki/WireBox.cfm#Virtual_Inheritance
// Declare base CFC
map("BaseModel").to("model.base.BaseModel");
map("UserService").to("model.users.UserService").virtualInheritance("BaseModel");
It's basically very similar to what Adam described above; a base class is created, and references to it's public members are placed in the sub class.
https://github.com/ColdBox/coldbox-platform/blob/master/system/ioc/Builder.cfc#L535
There's no reason why you can't build something similar but you should know this has already been done.
Full disclosure, I am a contributing member of the *Box community.