Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles
(untagged)

Interfaces vs Abstract Classes

0.00/5 (No votes)
31 Jul 2013 1  
Uses of Interfaces and abstract class

Interfaces and Abstract classes:  

Introduction  

As we know about the multiple inheritances, it’s the ability to provide base class functionality to its derived classes. Much time we are discussing that interfaces is the right solution to achieve multiple inheritance in C# because there is no direct support of multiple inheritance in C# then we think that interfaces only contains implementation so how it helps to get multiple inheritance and why we need interfaces if we can do this by abstract classes or otherwise. In brief, if you need shared behavior to derived classes then use abstract class or if you need plug gable element structure use interfaces because interface is only alternative of multiple inheritance in term of reusable component design not for shared functionality, it’s just define a contract to derived classes .

Abstract class and interfaces used to set abstraction layer in your code.

Similarity:

  • Abstract and Interfaces can’t be instantiated directly.
  • Like interfaces abstract class can also be declarative, if all members define abstract

Differences:

  • Abstract class may or may not have abstract method other than interfaces only declarative.
  • Abstract class can contain variable other than interface can’t.
  • Interfaces members are implicitly public; so you can’t use access modifiers to restrict access other than abstract class follows the general class rules.
  • We can’t use static and constant members in interface other than abstract class we can use.
  • A Class or Struct can be inherited from multiple interfaces but only from single abstract class.

But confusion is still on why, where and how we can use these types and how interfaces are alternative to multiple inheritances.

Interfaces contain a set of specifications for methods and members. As we all know that Base classes allows to build shared behavior in derived classes ,Which is useful when all the derived classes needs to have same feature related to one other. Interfaces provide you to create common behavior across the classes that do not share common Childs, in sense we can say you can up cast any object which implements an interface and you can handle them by using the same code. Using an interface confers the same benefits as deriving from abstract base class; Code can work with objects at a given level of abstraction and new classes can be defined with new implementation without modification of existing code but this can be done by abstract classes as well. We can say that a class can derived from single abstract class or otherwise other than a class can implement multiple interfaces.

To verify, let’s create a scenario to know what actually the benefit of using interface is and what the actual scenario where interfaces better than interfaces.

Overview:

Two library projects developed for same stuff one is developed by using abstract classes and other with abstract classes and interfaces. In brief this is just a demo project to know scenario based uses of abstract classes and interfaces.

Solution contains two library projects ProcessLibrary and ProcessAbstractLibrary both have the same functionality of Document Import and export. Process library has some additional interfaces IProcess,IImportProcess and IExportprocess other than in ProcessAbstractLibrary all work has been done by abstract and other classes without using interfaces ,Rest of the classes are same in both projects without any additional functional code .

Another class AprocessInfo implemented by DI (Dependency Injection) of Aprocess instance in ProcessAbstractLibrary and same has been done in ProcessLibrary apart of ProcessInfo class DI implemented by IProcess instance.

ClientProcessDisplay class have two static methods AbstractProcess() and InterfaceProcess() for client side XML Document import and export processes.

AbstractProcess():

Console.WriteLine("***********Abstract Export Process**************",  Environment.NewLine);
            string str = "<a>TEXTB<c>TEXTC</c></a>";

            //XMLExport exp = new XMLExport();
            AXMLExport Aexp = new AXMLExport(str);
            Aexp.FileNameTosave = "Test.XML";

            Console.WriteLine(Aexp.ProcessType.ToString(), Environment.NewLine);
            Console.WriteLine(Aexp.ExportType.ToString(), Environment.NewLine);
            Console.WriteLine(Aexp.FilePath.ToString(), Environment.NewLine);
            Console.WriteLine(Aexp.FileNameTosave.ToString(), Environment.NewLine);
            Aexp.Save();

            Console.WriteLine("***********Abstract Import Process**************", Environment.NewLine);

            //XMLImport imp = new XMLImport();
            AXMLImport Aimp = new AXMLImport("Test.XML");

            Console.WriteLine(Aimp.ProcessType.ToString(), Environment.NewLine);
            Console.WriteLine(Aimp.ImportType.ToString(), Environment.NewLine);
            Console.WriteLine(Aimp.FileName.ToString(), Environment.NewLine);
            Console.WriteLine(Aimp.Show(), Environment.NewLine);

            Console.ReadKey();

InterfaceProcess():

            Console.WriteLine("***********Export Process**************", Environment.NewLine);
            string str = "<a>TEXTB<c>TEXTC</c></a>";

            //XMLExport exp = new XMLExport();
            XMLExport exp = new XMLExport(str);
            exp.FileNameTosave = "Test.XML";

            Console.WriteLine(exp.ProcessType.ToString(), Environment.NewLine);
            Console.WriteLine(exp.ExportType.ToString(), Environment.NewLine);
            Console.WriteLine(exp.FilePath.ToString(), Environment.NewLine);
            Console.WriteLine(exp.FileNameTosave.ToString(), Environment.NewLine);
            exp.Save();

            Console.WriteLine("***********Import Process**************", Environment.NewLine);
            //XMLImport imp = new XMLImport();

            XMLImport imp = new XMLImport("Test.XML");

            Console.WriteLine(imp.ProcessType.ToString(), Environment.NewLine);
            Console.WriteLine(imp.ImportType.ToString(), Environment.NewLine);
            Console.WriteLine(imp.FileName.ToString(), Environment.NewLine);
            Console.WriteLine(imp.Show(), Environment.NewLine);

            Console.ReadKey();

Till now all is fine because there is no functional difference between both but now assumes if you want to create a single derived class for both import and export with existing ProcessAbstractLibrary assembly code.

XMLOtherDocument :AExportImport , AImportProcess
               {     //Implementation  }

It’s not possible with existing ProcessAbstractLibrary code, you have to create a separate code for this new class without using existing abstract class contract else you have to change your library code.

Let’s have a look to other library which developed with same functionality but by using interface contracts:

XMLOtherDocument: IExportProcess, IImportProcess
                {    //Implementation  }

Here you don’t need any change in your existing code and you can use existing contract without any trouble.

So now we can say that:

  • An interface is same as abstract classes as base class.
  • Interfaces can’t be instantiated directly .
  • Interfaces support events, indexers, methods, and properties.
  • Interfaces contain public methods without any implementation.
  • Interfaces are alternative of multiple inheritances. A class can inherited from one or more interfaces.
  • Interface provides loose coupling other than concrete class provide strong coupling.

Coupling: In Brief when one class has direct knowledge of other class refer as coupling. If dependent class has direct reference to concrete class then it‘s called strong coupling else when dependent class contains pointer to interface it’s called loose coupling.

Partial Interfaces: Interfaces can be used with partial keyword like partial classes as we know compiler combine the partial elements to create unified interface definition.

                    partial interface IProcess
                          {   void DataProcess();   }
                    partial interface IProcess
                          {   string ProcessType { get; } }

                    class Process : IProcess
                         {
                              public void DataProcess()
                                {     //Logic    }
                              public string ProcessType { get { return "Data"; } }

                          }

Explicit Interface Implementation: Multiple inheritances by using interfaces are quite easy until members are identical .Suppose two interfaces have same member like below:

interface IExportProcess {  void Save();   }

interface IImportProcess {  void Save();   }

Problem occur when XMLDocument object up cast to IExportProcess ,calls to the Save Method expecting different result then if the same method was called when the object up cast to IImportProcess .

To sort out this problem you can use explicit interface implementation as below;

                     class XMLDocument :IExportProcess,IImportProcess
                          {
                               public void IExportProcess.Save()
                                  {   //Logic    }

                               public void IImportProcess.Save()
                                   {  //Logic    }

                           }

When an object of class that uses explicit interface implementation is up cast to one of the interface types, .Net runtime ensures that correct member implementation invoked.

There are various method of using interface and abstract classes in design pattern it’s up to you how you want to handle them. I think this little work will helps you to understand the uses of abstract classes and interfaces.

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here