A Funny Java Flavoured Look at the World

Sunday, April 30, 2006

Interfaces vs abstract classes

I recently read an article titled interface vs abstract class and imagined an Alien versus predator type block buster movie, introduced in a boxing Rocky style of course

It is an interesting question, so I thought I would type it into google to see what else came up. I will assume the readers of this blog know the difference between interfaces and abstract classes but JavaRanch have this artice that states

"1. You can implement multiple interfaces at the same time, but only extend one class
2. An abstract class is allowed to contain implementation (non-abstract methods, constructors, instance initializers and instance variables) and non-public members"
Part of the argument regarding this question is also linked to theory that you should favour composition over inheritance. Abstract classes have to be extended which means they don't conform to a number of Object orientated rules which if you want to get a good grounding on it's worth reading Robert C. Martin articles on the subject, many of which can be found here

When I first starting to learn Java I really struggled to understand the use and idea behind interfaces they seemed very pointless to me. Abstract classes on the other hand were not so hard to understand (although not fully) because you can put some code in them. I think you start understanding the idea of both and then start to understanding when you should use one or the other is once you start thinking about the design of your code. I personally found this happened when reading the OO articles by Robert C. Martin and also seeing the good designs by reading a book on design patterns (head first design patters, very good). Once I saw that I could see the value of interfaces and abstract classes and the OO articles helped me to understand why the designs were good.

Back to the discussion at a hand, this site provides a good introduction to Abstract class and Interfaces. The JavaRanch article has these points to decide whether to use Abstract class or an Interface

"1. use an abstract class, if you want to provide common implementation to subclasses,
2. use an abstract class, if you want to declare non-public members,
3. use an interface if you want to provide the implementing classes the opportunity to inherit from other sources at the same time."
I think the important point to consider when decided if you want to use an Abstract class is will it contain code that will be used by the subclasses (classes that extend the abstract class). Will the subclass be the same as the baseclass (superclass) but with extra methods and code or/and will they override some of the superclass methods. So if the classes that will implement an abstract class or interface will need to use the same code then I would say you want this code to be an abstract class.

Be warned though you have to be cautious when deciding to use an Abstract class because it is then making the classes than extend it completely dependent on the abstract class. This can mean any changes you need to make to a core method can break all the classes that extend the Abstract class. On the other hand Abstract classes do allow you do add non abstract methods with out effecting the classes that extend it but if you add a method to an interface they all have to implement that method.

So when should you use interfaces. I usually think about interfaces as behaviours. Interfaces are a bit like contracts, a guarantee that the a class that implements them will have certain methods, they might not have anything in but we won't worry about that here. The classic example of interfaces is implementing algorithm's, which in my mind is a classic textbook example which you read, understand but then can never make it relevant to your work because there aren't many times you need to implement a number of different algorithms.

An example of interface implementation (in my opinion) is the sorting collections using the comparator. A quick summary of the comparator interface is used to order collections, it has two methods but I will just talk about compare(T o1, T o2) and it returns an int, Returns a negative integer, zero, or a positive integer as the first argument is less than, equal to, or greater than the second. It uses Generic functionality so T means a class. You extend comparator, implement the compare method which takes two objects you have made and then works out a way to decides whether the first object should be sorted higher than the second object.

This is an excellent example of using an interface correctly, it is a behavior, it is not something you would want to be an abstract class because each class would probably want to overwrite the compare function. Another point to consider when thinking about using an interface is would other classes want to use this functionality. Abstract classes have firm hierarchy, Interfaces can be implemented by any class anywhere.

Interfaces also have the advantage of allowing classes to implement many interfaces where as you can only extend one abstract class.

This article offers a brief discussion on Intefaces versus Abstract Classes and this discussion gives a number of opinions from different people which is useful.


Summary

I think it depends on the functionality and purpose of your planned functionality. If you want to create some default behaviour and provide some base code with abstract methods for extending classes to implement then abstract classes are the way to go, which is why they are often used in frameworks.

If you want to implement behaviour that could be used by many un related classes and you don't want a hierarchy for the classes that implement the code then you want to implement an interface.

Obviously I'm not an expert and I just giving my opinion on a very complex topic, so please for give me if I have written anything stupid or completely incorrect, it was a very interesting topic to try and write about, also a very tricky one. I would like to people to comment on their ideas on how they decide to use Abstract classes or interfaces. I never use to like Interfaces because you would have to write the code for each implementing class but now I realise that if you use the interface in the correct way this is a good thing and interfaces allow you decouple your code and protect your code from changes by allowing it easy to change the code behind the interface, especially adding in new implementing classes and using them.



3 Comments:

  • Actually your hints (or perhaps better what JavaRanch recommends) state sufficient criteria for the choice. If you have a requirement that determines completly what you have to choose it is too easy. The interesting question is what to choose when actually having a choice! My girl-friend asked the same question 4 years ago, while the obvious answer had been easy of course, for the remaining part I am still thinking. In the meantime I refactored as many interfaces into abstract classes as abstract classes into interfaces.

    By Anonymous Carsten Saager, at Mon May 01, 02:41:00 am 2006  

  • good point. I think often it's hard to see when you need an interface until you are refactoring and then you understand the needs of the class and realise it might be better suited to an interface.

    I suppose this is the same as an Abstract class, you could find that some of the methods of the implementing classes are the same and would thus be more suited to be an Abstract class.

    I think this is why there was quite a bit of information on the subject because there are times when you could choose both. When you could choose both I would probably think it was safer to choose an interface because it produces code that is not so coupled which is why a lot of literature recommends composition over inheritance.

    thanks for your comment, a very good point

    By Blogger Hosky, at Mon May 01, 02:51:00 am 2006  

  • Basically, You use an interfcae in a case where you wanna hide the implementation, or you dont know that in what way how it will be implemented.

    For example, take the HttpRequest. It is an interface. When you write your Servlet, you program to the interface. Not to the class which implements the interface. The Server, where your WebApp is running, will create the object of the class which implements HttpRequest and send as a parameter to the doGet/doPost methods.

    Now, TomCat server may name the class (which implements HttpRequest)as TomCatHttpRequest and WebLogic as WebLogicHttpRequest and some XYZ server as XYZHttpRequest. But, since they all implement the interface HttpRequest, they are BOUND to implement the methods present in the interface. So, as a programmer, when you code, you code to the interface and NOT to the underlying classes which implement the interface. Hence, the app runs in any WebServer.

    By Blogger Sen, at Tue May 02, 07:53:00 am 2006  

Post a Comment

Links to this post:

Create a Link

<< Home