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

Demystifying interfaces in C#

0.00/5 (No votes)
14 Apr 2014 1  
To clear some of the misconceptions about interfaces

Introduction

The purpose of this article is to demystify the misconceptions about Interfaces and to explore some of its uses which beginners may find mysterious.

Interfaces

What is the difference between an abstract class and an interface? Why should we go for an interface when we have abstract class that performs the similar action? These questions are quite common and have been asked in almost all the developer job interviews. Interfaces are for providing a good level of abstraction. Like that, the answers by the beginners for those questions are also in an abstract manner J

People answer the first and foremost thing which they think the only actual answer. It is not possible to do multiple inheritance (both in case of Java and .NET). Yes, but why you need to inherit multiple classes to a class. If it is a frequently used stuff, the technology you work for should have it supported right? The technologies like .NET and Java are not supporting for many reasons. (http://blogs.msdn.com/b/csharpfaq/archive/2004/03/07/why-doesn-t-c-support-multiple-inheritance.aspx)

Okay, we can achieve multiple inheritance for an extreme by using multiple interface inheritance. Is that the only reason interface are added to the languages? No! Interfaces are primarily for abstracting the object’s core implementation from the consumers. Why should we have an abstract class then? When we have some common concrete code, that has to be shared among the derived classes, the abstract class would be the right choice.

Object creation will of course come with a cost. For example, in .NET, when we create an object, the object’s memory will be allocated in the heap and the pointer for that object will be put on the thread stack. Along with the actual object, all the parent, grandparent and great grandparent objects will be created. So, if we use an abstract class which has no concrete method in it, when we create an object for the derived class, objects for both the parent and the child will be created.

For example,

BaseClass b = new DerivedClass(); 

DerivedClass d = new DerivedClass();

Both the above examples will be creating object for DerivedClass which in turn create a base class object. While using the instance b, the abstracted version of DerivedClass will only be accessible. While using the instance d, the full version (both the overridden methods of the BaseClass and the concrete methods of DerivedClass) of DerivedClass will be accessible. Okay, one more basic question. From whom we are protecting the derived class elements? Does someone will corrupt/hack the object? Not all the time! It depends on the problem domain. The primary objective of abstracting the object from the consumer is to decouple the consumer and the object. So, when some of the internal behaviour in the object gets changed, the object’s consumer doesn’t require changing their code as well.

Interfaces will also be providing the similar level of the abstraction like the abstract class. But, unlike the abstract class, there will not be a separate object created for interface instance upon using it. And of course, we can do multiple interface inheritance and can use the required interface to create the object in the consumer to achieve various levels of abstraction.

That’s all? No! Interface shall also be used to group the methods/properties with respect to those purposes and the way those should be available to the clients (who make use of the interface to access the object). And hence, the consumer shall not worry about the other behaviour the object has. The object’s state will also not be changed by mistaken access and the client code will be perfectly decoupled.

Consider the following example:

        public interface IEmployee
        {
            string ID;
            string Name { get; set; }
        }
        public interface IPayrollMember : IEmployee
        {
            double Salary { get; set; }
        }

        internal class Employee : IEmployee, IPayrollMember
        {
            //IEmployee members
            public string ID
            {
                get;
                set;
            }
            public string Name
            {
                get;
                set;
            }
            
            //IPayrollMember member(s)
            public double Salary
            {
                get;
                set;
            }
        }

Consider the application has a class defined for Employee to manipulate employee details. The class is being used by many applications in the same company. As we have two interfaces IEmployee and IPayrollMember, for the module used by gate security, IEmployee interface shall alone be exposed and for the payroll department, the interface IPayrollMember shall be exposed (which has IEmployee members too with the help of interface inheritance). So, at any cost, the developer who develops the gate security application will not be aware of what else an employee object might contain and hence his code will be perfectly decoupled from other members the Employee class has. So, any changes happens inside Employee class, the security module will remain unaffected.

Wait! How can you say that the security module will not be aware of the whole Employee class? What if the developer creates the employee object directly like:

Employee e =new Employee();

Yes, and that’s why we made Employee class as internal. So, we should also expose another class that helps the consumers to create the required object.

        public class EmployeeFactory
        {
            public IEmployee GetEmployee(string id)
            {
                return CreateEmployeeObject(id);
            }
            public IPayrollMember GetPayrollMember(string id)
            {
                return CreateEmployeeObject(id);
            }
            private Employee CreateEmployeeObject(string id)
            {
                return new Employee(id);
            }
        }

The gate security app developer shall make use of GetEmployee method to get the employee details and the payroll person shall make use of GetPayrollMember to get the required object.

Disclaimer:

The intention of this article is not to cover everything about interface but to demystify some of the misconceptions. Factory pattern used in this article is just to show how the other behaviour of the class shall be hidden. The object creational logic can even be in some other better way!

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