4

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?)

Community
  • 1
  • 1
jessieloo
  • 1,759
  • 17
  • 24
  • 1
    This question discusses multiple inheritance in Java: http://stackoverflow.com/questions/21824402/java-multiple-inheritance . You may find it useful. – Sean Walsh Aug 28 '14 at 21:56
  • Yes, that's what I'm trying to do and it's a much better example! So, now how to do it in CF? – jessieloo Aug 28 '14 at 22:01
  • 2
    Personally, I'd probably use composition to accomplish this (as described in the second and third answers to the question above). The other option would be to have a superclass that can walk, talk and sleep, and then override the irrelevant methods in the extending classes to throw an exception, but that has a *really bad* code smell to me. – Sean Walsh Aug 28 '14 at 22:06
  • @SeanWalsh I strongly agree with your sentiment here. – Adam Cameron Aug 29 '14 at 08:23

2 Answers2

2

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.

Adam Cameron
  • 29,677
  • 4
  • 37
  • 78
1

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.

Brad Wood
  • 3,863
  • 16
  • 23