Interface vs. Abstract Class

 
With my personal experience I can say, this is question has always been a favourite question for the interviewers. But there are very few online resources where you can find a proper reply for this though I have already published this article before in another blog.
Let’s just dig into Interface & Abstract class first.
What is an Interface?
An interface is a named collection of method definitions without implementations.
Interface is actually a template in Java. It contains only the method declarations. The class that implements the interface contains the definitions for the abstract methods of the interface. Interface can also contain fields, but the fields should be static & final. On the other hand, the abstract methods declared in the interface are abstract & public.
We need to remember some points regarding interface:









1. All the methods are abstract & public
2. All the fields are static & final.  
3. Interface files always have .java extension although they are not classes.
4. Byte code of an interface always appears in a class file.
5. We can’t create object of an interface.
6. Unlike inheritance, a class can implement more than one interface.
7. One very important point – If a class is implementing an interface, the class will have to implement all the methods declared in the interface. Otherwise it will throw a compilation error.
8. Any number of methods & variables can be declared in an interface.
9. An interface can extend another interface like a class extends another class.
Now, these all the definitions are somehow a bit theoretical. We need to use interface practically. For that, we need an Interface, a class that implements the interface & a main method from which the caller class (which implements the interface can the called)

Example for simple interface implementation :
Interface :
   1:  

   2: public interface interfaceTemplate{

   3: static final String 

   4: test1= "test";

   5: public void method1();

   6: public void method2();

   7: }


Class that implements interface interfaceTemplate:


   1:  

   2: public class InterfaceCaller implements 

   3: interfaceTemplate {

   4: @Override

   5: public void method1() {

   6:  

   7: System.out.println("in method1");

   8:  }

   9: @Override

  10: public void method2() {

  11: // TODO Auto-generated method stub

  12:  

  13: System.out.println("in method2");

  14:  }

  15: }

The class which is accessing the interface interfaceTemplate using InterfaceCaller:


   1:  

   2: public class InterfaceMain {

   3: public static void main(String 

   4: args[])

   5:  {

   6:  

   7: interfaceTemplate it = new InterfaceCaller();

   8:  

   9: it.method1();

  10:  

  11: it.method2();

  12:  }

  13: }

When you will run this in your machine, you are going to get this result:
in method1
in method2
Example for an interface extending another one:
Interface:


   1:  

   2: public interface SuperinterfaceTemplate {

   3: public void 

   4: methodInSuperInterfaceTemplate();

   5: }


Interface which extends SuperinterfaceTemplate


   1:  

   2: public interface interfaceTemplate 

   3: extendsSuperinterfaceTemplate{

   4: static final String 

   5: test1= "test";

   6: public void method1();

   7: public void method2();

   8: }

The class which is implementing both the interfaces above:


   1:  

   2: public class InterfaceCaller implements 

   3: interfaceTemplate {

   4: @Override

   5: public void method1() {

   6:  

   7: System.out.println("in method1");

   8:  }

   9: @Override

  10: public void method2() {

  11: // TODO Auto-generated method stub

  12:  

  13: System.out.println("in method2");

  14:  }

  15:  

  16: @Override

  17: public void methodInSuperInterfaceTemplate() 

  18: {

  19: // TODO Auto-generated method stub

  20:  

  21: System.out.println("in 

  22: methodInSuperInterfaceTemplate" );
  23:  }

  24: }

The class that has main method & accesses the interfaces:


   1:  

   2: public class InterfaceMain {

   3: public static void main(String 

   4: args[])

   5:  {

   6: // calling methods in interfacetemplate 

   7: &Superinterfacetemplate

   8:  

   9: interfaceTemplate it = new InterfaceCaller();

  10:  

  11: it.method1();

  12:  

  13: it.method2();

  14:  

  15: it.methodInSuperInterfaceTemplate();

  16: //creating an object of the Superinterfacetemplate& 

  17: calling the method directly

  18:  

  19: SuperinterfaceTemplate sit = new InterfaceCaller();

  20:  

  21: sit.methodInSuperInterfaceTemplate();

  22:  }

  23: }

When you are running this code in your machine you are going to get a result like this:
in method1
in method2
in methodInSuperInterfaceTemplate
in methodInSuperInterfaceTemplate
==================================================================
What is Abstract Class?
An abstract class is a class that is declared abstract—it may or may not include abstract methods. Abstract classes cannot be instantiated. Abstract classes can be accessed only by extending them.
There are some key features we should remember about abstract class:
1. All the methods in Abstract class may or may not be abstract. We can define methods inside an abstract class.
2. An Abstract class can’t be instantiated.
3. If any subclass inherits an abstract class, that  contains abstract methods, then the subclass must implements all the abstract methods of the abstract class.
4. Just like normal Interface & classes, an abstract also can extend another abstract class.
Example for a simple abstract class implementation:
Abstract Class:


   1:  

   2: public abstract class AbstractClass 

   3: {

   4:  String s = 

   5: "srijani";

   6: abstract void method1();

   7: public void method2()

   8:  {

   9:  

  10: System.out.println("Inside Method2 : "+ 

  11: s);

  12:  }

  13: }

A class extending the abstract class


   1:  

   2: public class CallingAbstractClass 

   3: extends AbstractClass{

   4: @Override

   5: void method1() {

   6: // TODO Auto-generated method stub

   7:  

   8: System.out.println("In Method1");

   9:  }

  10: }

The main method :


   1:  

   2: public class AbstractMainClass {

   3: public static void main(String 

   4: args[])

   5:  {

   6:  

   7: CallingAbstractClass c= new CallingAbstractClass();

   8:  

   9: c.method1();

  10:  

  11: c.method2();

  12:  }

  13: }

Example for an abstract class inheriting another abstract class:
Superclass:


   1:  

   2: public abstract class 

   3: SuperAbstractClass {

   4: abstract void method3();

   5:  

   6: }

Abstract class:


   1:  

   2: public abstract class AbstractClass 

   3: extends SuperAbstractClass{

   4:  String s = 

   5: "srijani";

   6: abstract void method1();

   7: public void method2()

   8:  {

   9:  

  10: System.out.println("Inside Method2 : "+ 

  11: s);

  12:  }

  13: }

A simple class extending both the abstract classes


   1:  

   2: public class CallingAbstractClass 

   3: extends AbstractClass{

   4: @Override

   5: void method1() {

   6: // TODO Auto-generated method stub

   7:  

   8: System.out.println("In Method1");

   9:  }

  10: @Override

  11: void method3() {

  12: // TODO Auto-generated method stub

  13:  

  14: System.out.println("In Method3");

  15:  }

  16:  

  17: }

Main Method:


   1:  

   2: public class AbstractMainClass {

   3: public static void main(String 

   4: args[])

   5:  {

   6:  

   7: CallingAbstractClass c= new CallingAbstractClass();

   8:  

   9: c.method1();

  10:  

  11: c.method2();

  12:  }

  13: }

When an Abstract Class implements An Interface !!!
Although we have already told that if a class implements an interface, it will have to implement all the methods mentioned in the interface, it if not fully correct. If an abstract class implements an interface, it is possible that the abstract class may not define all the methods that are present in the interface.
When to use interface & when to use Abstract class ?

This has been a favorite question for all the interviewers I guess!! And, a very little people know it correctly. I was searching for this answer for last few days & that is the actual reason I am writing today in this blog regarding Abstract Class & Interfaces.
I am giving my personal opinion for this answer. Everyone, please feel free to share your opinion for this answer & correct me if am answering this question wrong.
In my opinion, when to use interface & when abstract class is purely requirement specific. For example, we need to implement some logic (we can take an example for color of car, internal amenities like A.C etc.) for any 4 wheeler that is produced by a certain company. So it is clear that if that company produces 2 different models of 4 wheelers, we have to write the logic 4 times for each model of 4 wheelers produced by that company.


   1:  

   2: public interface 4wheelers{

   3: public void color();

   4: public void amenities();

   5: }

Class implementing the interface for Model1:


   1:  

   2: public class Model1 implements 

   3: 4wheelers {

   4: @Override

   5: public void color() {

   6:  

   7: System.out.println("white");

   8:  }

   9: @Override

  10: public void amenities() {

  11: // TODO Auto-generated method stub

  12:  

  13: System.out.println("A.C is 

  14: present");
  15:  }

  16: }

Class implementing the interface for Model2:


   1:  

   2: public class Model2 implements 

   3: 4wheelers {

   4: @Override

   5: public void color() {

   6:  

   7: System.out.println(“Black");

   8:  }

   9: @Override

  10: public void amenities() {

  11: // TODO Auto-generated method stub

  12:  

  13: System.out.println("
A.C is not
  14: present");

  15:  }

  16: }

Then, where we can use Abstract Class?
Abstract class can have abstract methods as well as method declarations in it & that’s the key of our answer. So, if we want to create some properties for those 2 models which are same for both are cars as well as some properties which are not same for the models, then we will use abstract class.
So, the abstract class defined is :


   1:  

   2: public abstract class 

   3: 4wheelers{

   4: abstract void color();

   5: public void noOfWheels()

   6:  {

   7:  

   8: System.out.println("It is always same : 

   9: ”+4);

  10:  }

  11: }

And, the classes that are extending the abstract class are:


   1:  

   2: public class Model1 extends 4wheelers 

   3: {

   4: @Override

   5: void color() {

   6: // TODO Auto-generated method stub

   7:  

   8: System.out.println(“White");

   9:  }

  10:  

  11: }

  12: public class Model2 extends 4wheelers 

  13: {

  14: @Override

  15: void color() {

  16: // TODO Auto-generated method stub

  17:  

  18: System.out.println(“Black");
  19:  }

  20:  

  21: }

Hope you all have enjoyed reading!!!
Please feel free to share your comments.


"Knowledge is knowing that we cannot know." - Ralph Waldo Emerson

5 comments :