Friday, 30 September 2011

Abstract vs Interface

Abstract Class

These classes are either partially implemented, or not at all implemented.
  • This class can contain declarations and also implementations. 
  • We cannot make instance of Abstract class. We must inherit to use this class.
  • A non-abstract class derived from an Abstract class must include implementations for all inherited abstractmethods.
  • Abstract class can contain abstract methods, abstract property as well as other members (just like normal class).

Interface

Interface is a pure abstract entity:
  • It contains only the declaration.
  • We cannot make instance of an Interface. We must inherit to use Interface.
  • A class which implements the interface should implement all the members of an Interface.
  • Members of an Interface are always public.

Few Advantages

An advantage of Abstract class over Interface

If you want to have additional functionalities for the interface, you must implement the new ones in all of the classesthat implement the changed interface. The code will not work until you make the change. But if you want to have additional functions to the Abstract class, you can have default implementation. Your code still might work without many changes.

An advantage of Interface over Abstract class

A class can inherit multiple interfaces but can inherit only one class.
Now let us discuss the most important part - when to use Abstract and when to use Interface.

When to Use Abstract and When to Use Interface

Let me explain it with reference to the scenario.
Let us take a classification called Human. As it is a very general classification, I can put all the Human related common data in Abstract class. These common data could be First Name, Last Name, Gender, Education, Occupation, Residence, etc. with some functions as virtual (or overridable), e.g., an occupation which differs from human to human.
Aim of Interface: We want the implementing object to acquire this ability.
Aim of Abstraction: We want the derived object to belong to some group. Abstraction gives the Identity to the derived object.
The sentence "Object A is a Human" is more meaningful than the sentence "Object A is an object which has the ability to walk." (Human can walk, an animal, a bird, a machine - consider it is a robot ... that can also walk.)

Why I chose interfaces IEat, IWalk, IDance and ISing

I may want Object A to walk in the morning, to eat in the afternoon or to dance in the evening, or I may not be aware at a particular time what these objects should be doing. The capability of Object A at a particular time is unknown to me. Also every derived object may need not posses the quality of walking, or dancing, or singing. An infant cannot walk, as you know everybody cannot dance and sing. So I created these interfaces so that I can define the combination of these capabilities for different objects explicitly.
Refer to the image below for a more clearer view.

Take an example of .NET interfaces IDisposable or IComparable. We implement these interfaces only if necessary. We implement IDisposable mostly when we want to handle COM components and IComparable to compare and sort the objects in an Array.
If you want your class to have an Identity of Form, you must inherit Form class and you can add the ability to dispose, by implementing IDisposable, only if you want to dispose it manually.

Polymorphic Behavior

As I told you, interface adds to the capability of an Object, this means I can have an Object which eats while walking, and the same Object which can dance, and also sing well. This gives polymorphic behavior (single object –multiple capabilities) to the object.
Let me explain this with the help of code.
namespace TestAbstractVsInterface
{
    //Abstract class

    abstract class AbstractHuman
    {
        public abstract string name { get; set;}
        public abstract string qualification { get; set;}
        
        //Remaining code goes here
        //.
        //.
        //.
        //.
    }

    //Interfaces

    interface IEat
    {
        void eat();
    }

    interface ISing
    {
        void sing();
    }

    interface IWalk
    {
        void walk();
    }

    interface IDance
    {
        void dance();
    }

    //Class which inherits abstract class and implements interfaces

    class MyClass : AbstractHuman, IEat, ISing, IWalk, IDance
    {      
        private string strName = "Arati Kadi";
        private string strQualification = "";
        
        public override string name
        {
            get { return strName; }
            set { name = value; }
        }

        public override string qualification
        {
            get { return strQualification; }
            set { name = value; }
        }

        public void eat()
        { 
            //Related code
        }

        public void sing()
        { 
            //Related code
        }

        public void walk()
        { 
            //Related code
        }

        public void dance()
        { 
            //Related code
        }

//The code snippet below checks by what type class could be //accessed as.

        public void getAbilities()
        {
            if (this is IEat)
                Console.WriteLine("MyClass can eat");                
            if (this is IWalk)
                Console.WriteLine("MyClass can walk");                
            if (this is ISing)
                Console.WriteLine("MyClass can sing");              
            if (this is IDance)
                Console.WriteLine("MyClass can dance");               
        }        
    }  

    //Test Myclass

    class testClass
    {
        MyClass objMyClass = new MyClass();

        public void test()
        {
            objMyClass.getAbilities();
        }
    }

 }

Output

MyClass can eat                  
MyClass can walk                
MyClass can sing
MyClass can dance
Technically speaking, here the class is used as more than one type. It is used as four Interface Types. It can also be used as its own type and also the type of its base class.

Reusability

Let us consider the same abstract Human class which has the virtual function Eat instead of an Interface IEat.
Now I want to create a class called Bird. As a Bird can also eat, I want to reuse the function which is already there in Human class. Suppose, just because abstract Human class has the function to eat, I cannot derive a Birdclass from that. I will tend to change the Bird's identity by doing so, or I may load unnecessary properties to theBird that could be an education, or employment, or may be the last name. Even worse I may need to change theabstract Human class so as to include the common behaviors of Bird category. This is totally senseless and messes up the class and objects. Instead, I can have another Abstract class for Birds and choose to have an interface called IEat, which could be implemented by an object of Human and also an object of Bird.

Again I want to mention .NET interfaces IDisposable, IComparable (and many). These are available in Systemnamespace and you are reusing to implement with required classes.

Conclusion

  • Abstract class gives an Identity to the derived object.
  • Interface extends the ability of an object.
  • Interfaces give polymorphic behavior.
  • Abstract class also gives polymorphic behavior. But it is more meaningful to say that Abstract class simplifies versioning, as the base class is flexible and inheriting class can create many versions of it by additional functions and also by implementing Interfaces.
  • Interfaces and Abstract Classes both promote reusability.

No comments:

Post a Comment