Win a copy of Kotlin in Action this week in the Kotlin forum!
  • Post Reply Bookmark Topic Watch Topic
  • New Topic

when should i use abstract class and when i should i interfaces  RSS feed

 
kesava chaitanya
Ranch Hand
Posts: 140
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
when should we use abstract classes over interface or vice versa;i am getting this question regulary;how should i give proper answer.
whatever methods we define in abstract class same thing we can do in interfaces;
so what we can achieve with abstract class;
bye
chaitanya
 
Joseph Kampf
Greenhorn
Posts: 26
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
The main diffrence between abstract classes and interfaces is that abstract classes can have some implementation.
This can be used in a situation where there is some core functionality that is common but a couple of operations that are sub-class specific. You can have the Abstract class have implementation of this core functionality and call the abstract methods (that will be implemented by the sub class).
Also Java does not allow multiple inheridance for classes. So if you suspect that your sub class will need to implement multiple interfaces (Interfaces I mean the method signatures not Java interfaces) then you will have to use the Java interfaces.
Anyway, net-net, my rule of thumb has always been, if there is no default behavior that goes along with those abstract methods, then make it an interface.
Joe
 
sever oon
Ranch Hand
Posts: 268
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Interfaces are about setting a contract, an agreement. When a class implements an interface, it agrees to meet the contract set out by that interface. Interfaces are about defining what operations are available. Classes (including abstract classes), on the other hand, are not *just* about defining what operations are available, but also *how* those operations are carried out.
Here is a very trivial example that you may find instructive. If I am interested in defining an operation increment(), and I know that most subclasses will vary in the way they choose to implement that increment(), I should put it in an interface. Using an interface, I am simply saying that implementing classes will take these arguments and return this result, without regard for how this operation is carried out.
If I am defining an increment() operation, and I know that most if not all subclasses not only want this operation *defined*, but also would like the *means by which it is carried out* defined, then I would put it in an abstract class.
What about a "pure" abstract class, with no method implementations, only abstract methods? Is there a difference between this and an interface (besides the obvious restriction that Java only allows a class to extend one class, whereas it can implement many interfaces)?
Yes. When you write a "pure" abstract class, this is a statement about future maintenance. When you choose an abstract class in this case, you are saying, "I don't have any implementation right now that subclasses would be interested in, but as this project evolves and new versions are released, if ever one of these methods are made concrete subclasses will mostly be interested in those implementations."
This is a very rare circumstance, but it does happen. Most of the time, it is appropriate to prefer interfaces to classes. This is because an interface is the only way to nail down some aspect of a design without regard for implementation details. This is very important to do, and it is also important to nail down these aspects of design using interfaces because you're putting a stake in the ground saying, "This is an aspect of the design on which the evolution of the project hinges." By writing an interface, you are effectively fixing this contract as a long-term part of the design. If you write a good design and fix all the right aspects of it, you can make sure you are writing an extensible, flexible system.
For example, let's say you're designing a geometry package. You might think it's a good idea to have an abstract Shape class, and have Rectangle, Trapezoid, etc, extend that class. There are several things you should be able to do to anything that calls itself a "shape": get the length around the perimeter, rotate it about its center, get the number of sides, etc. If you write Shape as an abstract class, you might find that you can provide default implementations of these methods that "kind of" make sense...but by providing implementations you could be fixing points of your design that should remain open. If you choose to simply mark these methods as abstract, you are saying that these points are open for now, but in a future version they may not be. This unwillingness to nail down this aspect of the design forms a shaky foundation. Classes that do extend Shape are depending upon a class that is open to changing in any way that a class can over several versions of evolution. It is generally bad to set up a large base of code that is dependent on an unstable foundation.
So, instead, write Shape as an interface and all you have to do is define the operations. Classes that implement this interface can be guaranteed that it will remain relatively stable because interfaces cannot undergo many of the changes that classes can as projects evolve. A stake is in the ground that fixes in your project what it means to be a shape, and fixes it in a way that is unchangable.
In some cases you will find the need for both...you'll want several classes to get the advantages of implementing an interface, but at the same time they do have code that is likely to be the same. No sense in repeating it:

In the above code sample, you can see how the getNumPoints() code is shared amongst all of the concrete shapes (circle, square) without each having to rewrite that code. Plus, you can see how all of the advantages of having Shape expressed as an interface is intact--no outside code can depend on AbstractShape because the class is marked protected. Only subclasses even know about its existence (and classes in the same package, but presumably those are written by the same developer as the AbstractShape class itself, and he would know better than to have a reference of that type floating around in his own code).
So, any outside code that wants to refer to Circle and Square objects polymorphically has no choice but to refer to them as Shapes, yet they still get the benefit of inherited code. The drawback--these two classes, because they extend AbstractShape, must agree that they are primarily AbstractShapes implementation-wise. They are unable to extend another class. This is a mild drawback at best, though, because if you think about it, it's a trivial thing to have a class that doesn't want the numPoint code to simply implement Shape directly, write its own version of that code (if it's not using AbstractShape's implementation, than it wouldn't want to share that code anyway), and then it can inherit implementation from whatever other place it wants.
In summary...the simple answer to your question that I've found most interviewers look for is: In Java, a class can only extend one other class, but it can implement many interfaces. That is obviously correct, but doesn't get at the heart of the matter--it simply begs the question, "Why did the designers of Java make that decision?"
The more complicated answer is: when a class extends another class, a statement is made that the subclass will want the superclass' *implementation* on an ongoing basis. If that superclass' code changes for a future version, it is expected that *all* subclasses will want that change. When a class implements an interface, the statement being made is different; the subclass is simply agreeing to deliver a certain result if the conditions specified by the interface are met by the caller.
sev
 
Jeroen Wenting
Ranch Hand
Posts: 5093
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
In general use an abstract class if part of the implementation is known in advance, an interface if not.
For example, I have written an abstract class and a series of implementing classes.
The abstract class has all the boilerplate code to handle the user interaction, setting up the backend calls, etc. etc. for all the implementing screens, the derived classes just add some little bits using the hooks provided through a set of abstract methods.
In this particular case it's some dozen servlets that are identical except for the screen name and a backend job launched from each.
All the derived classes implement themselves are functions to set the screen name to the HTTP request (from which it is read in a common JSP and displayed) and to start the backend task (in this case a printrun) using the data returned from the client (in this case very little).
The whole is itself derived from another abstract class in the framework that adds more boilerplate code and handles things like input validation and forwarding to the correct servlets/jsps/whatever based on configuration files.
We just implement a custom class called from that servlet based on the same config file that implements the hooks set in that abstract class.
If the code is all different between implementations, an interface is a better choice as it does not prevent inheriting from another class.
I've implemented those for example to create a group of classes that all have the same public interface but different implementation.
For example different classes, each implementing an interface to some backend functionality, could benefit from a standardised public interface.
If each had a function retrieve(), store(), delete(), execute(), etc. they would be a lot easier to substitute for each other while the implementation details can differ enormously.
By defining those methods in an interface and having your classes implement that you guarantee to your users that your class behaves as expected (as long as you don't abuse that confidence of course).
 
It is sorta covered in the JavaRanch Style Guide.
  • Post Reply Bookmark Topic Watch Topic
  • New Topic
Boost this thread!