Friday, October 27, 2006

Mutually Exclusive Interfaces

Jason Nussbaum has posed a nice juicy thought experiment - how do you handle mutually exclusive interfaces? I started typing a comment, but it got too long, so here's my take on it :

The question was:

Had a thought: how do people handle mutually exclusive interfaces?

I suppose there's no such thing as mutually exclusive interfaces from a code perspective, but from a logic perspective, there may be. For example, let's say you do one of two things based on whether a class implements one of two interfaces. What do you do if something implements both?


It's a conceptual problem - as Jason says, there's not really a technical way that interfaces could be mutually exclusive. You can think of it this way - if an object X implements interface Y, then what you're really saying is "X can act like a Y". So there's no reason why X can't also act like a Z, depending on the situation.

There are so many ways you could tackle this problem. You could introduce a super-interface:


public interface DeadOrAlive{ public boolean isAlive(); }

public interface Dead extends DeadOrAlive{
public void startToSmell();
}
public interface Alive extends DeadOrAlive{
public void breathe();
}


...and thus force implementers of Dead or Alive to provide a method which indicates if they are alive or not. This feels like a bit of a kludge, but to my mind, less so than without.

You could add Exceptions onto the signature methods of Dead and Alive, which might throw NotDeadException and NotAliveException respectively - but this actually feels more kludgey to me than the first case.

I think the "proper" way to think of this is maybe the biggest kludge of all - as your object model is meant to reflect the real-world problem that you're modelling, if it produces this kind of conflict then maybe you need to re-think your model!

- unless, of course, your name happens to be Schrödinger...


public interface Alive{ public void breathe(); }
public interface Dead{ public void startToSmell(); }

public class Cat implements Dead, Alive
{
public void startToSmell();
public void breathe();
}

public class Box
{
private Cat cat;

public void putCatInBox();
}


...eep, lame quantum physics jokes on a Friday?! I think it's time for coffee...

2 comments:

stephen booth said...

Here is a nasty hack to force two interfaces to be mutually exclusive. Put a method in each interface with the same name and parameters but a different return type. As java does not allow a class to have 2 method signatures that differ only in return type you won't be able to produce a compiling class that implements both interfaces. Its not nice but its going to work.

Alistair Davidson said...

Eep! - yes, that'd do it.... and yes, it's really quite nasty... nice one.