Question

What is considered general best practice:

Reference via the super type?

public class BirdFeeder{

    public Feed(Bird bird){...}

}

Or via a Interface

public class BirdFeeder{

    public Feed(IBird iBird){...}

}

Personally I prefer interfaces but I'm not quite sure why, to me they just feel 'cleaner'. I would like a better understanding of why I would choose one over another.

Thanks

Was it helpful?

Solution

You are correct about the interfaces, they offer you more flexibility in designing your inheritance hierarchy.

Suppose that you have a hierarchy that starts with a base class Bird, and continues down to various species of birds. Now suppose that you would like to add a mechanical bird to the hierarchy of birds, but you would rather derive it from the Robot base class. If your feeder takes Bird arguments, your mechanical bird would need a special feeder. If the feeder take an IBird, however, there would be no problem sending a RoboBird to it, as long as it implements the IBird interface correctly.

OTHER TIPS

If by "super type", and your comparison to interfaces, I'm guessing you want to focus on base abstract classes. (though you can use non-abstract base classes, but generally even an abstract class with no abstract members tends to communicate to the developer that it's intended to be implemented/inherited and doesn't stand on its own as a type)

There is no overall "best practice" when it comes to base/abstract classes vs interfaces. They both have their places in design practices. Really, the best practice comes about from the design you're implementing.

Probably the biggest difference when it comes to you design considerations is that base/abstract classes can only be inherited whereas interfaces can be implemented on any sort of class.

(EDIT: pilotcam came up with a far better example, see his comment to the question) From your bird example, say for example you wanted to handle different birds like Parrots, Albatross, and Penguin and they all inherit from Bird. But then your application also handles Dinosaur types. You get to implementing Archaeopteryx. Does it inherit from Dinosaur or from Bird? Now if instead Bird was an interface, you could simply have class Archaeopteryx : Dinsoaur, IBird. This example is a bit contrived (there's a better one I'm sure), but hopefully it's good enough.

Of course, base/abstract classes are nice too. For example, by combining access modifiers, you could take advantage of perhaps implementing an internal method to which your API accesses implementations but outside consumers of the class cannot.

There really are a slew of reasons to use one over the other, and neither one is really "better" to code against. It really depends on your application design, and arguably the metaphor you're coding against; what those objects are representing. Is your object actually a bird, or does it only behave like a bird? Does your API care? What will be better to maintain for your work?

Here's some more reading: Interface vs Abstract Class (general OO) (take note of all the "linked" similar questions to this one)

Use an abstract class for when you want to implement a set of behaviours in descendant components.

An interface when you want to implement a set of behaviours over a number of classes that have no useful common ancestor.

There are a lot of situations, when you could use either. In general I've found that I can rework a design that uses interfaces, get the new stuff and not get locked into a set of horrible compromises. I'd rather define an interface and then have an abstract class implement it for it's descendants than have no interface. It's a trivial amount of extra work at the start that can huge benefits later.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top