Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is it possible to avoid using type checking in this example?

Sorry for the poor title, can't think of a succinct way of putting this..

I'm thinking of having a list of objects that will all be of a specific interface. Each of these objects may then implement further interfaces, but there is no guarantee which object will implement which. However, in a single loop, I wish to be able to call the methods of whatever their further sub-type may be.

Ie, 3 interfaces:

public interface IAnimal { ... }
public interface IEggLayer { public Egg layEgg(); }
public interface IMammal { public void sweat(); }

this would then be stored as

private List<IAnimal> animals= new ArrayList<IAnimal>();

so, instances added to the list could possibly also be of type IEggLayer or IMammal, which have completely unrelated methods.

My initial instinct would be to then do

for(IAnimal animal : animals) {
  if(animal instanceof IEggLayer) {
    egg = ((IEggLayer)animal).layEgg();
  }
  if(animal instance of IMammal) {
    ((IMammal)animal).sweat();
  }
}

But I have always been told that type checking is a sign that the code should really be refactored.

Since it could be possible for a single object to do both [platypus, for example], meaning that a single doFunction() would not be suitable here, is it possible to avoid using type checking in this case, or is this an instance where type checking is classed as acceptable?
Is there possibly a design pattern catered to this?

I apologise for the contrived example as well...
[Ignore any syntax errors, please - it's only intended to be Java-like pseudocode]

I've added lvalue to the EggLayer use, to show that sometimes the return type is important

like image 651
Farrell Avatar asked Nov 02 '09 01:11

Farrell


1 Answers

Clearly your IAnimal interface (or some extension thereof) needs a callAllMethods method that each implementer of the interface can code to polymorphically perform this task -- seems the only OO-sound approach!

like image 93
Alex Martelli Avatar answered Sep 27 '22 23:09

Alex Martelli