Introduction
Big question almost posed by new oriented object programmers or students whose want to understand the divergence between those two concepts. The problem is that most answers to this question seem to be not enough clear or bring a little bit confusion to the mind, especially for students or programmers issued from other language programming environment such as the C++ programming environment which supports the multi inheritance or even from VB 6.0 as a none fully oriented object programming environment where Interfaces and abstract classes aren't brought into front frequently. At the other hand, most answers to this question focus on the theory side "using UML Diagrams" and neglect the practical side of the issue. For most people whose answering this question, they forget that demon resides in the details and details can be discovered and understood nearly when practicing.
Well, I can decompose the question into three sub questions. Has the interface existence a meaning as the class and especially the abstract form of the class is giving us the alternative to define abstracts members exactly like an interface? In witch case should one use an interface and in witch other case should he use a class? What can bring the interface to us?
Well, I will respond those tree questions each one in a separate article. In this first one, we try to investigate, parse and explore the nature of both the class and the interface concepts and I will focus on the last one as for many people, the dot net environment is already well-known, however, they don't have been familiars with interfaces concept yet. In second article I will try to explain the divergence between the two concepts through the function of each one. Finally, in the third article I will demonstrate some other functions provided by the interface based programming technique to discover what can it brings over the class one.
In practice, there are some differences between an Interface and a class in nature and in function. The purpose of this article is to treat the issue from a practice point of view, Of Corse, within the .Net context and gives some techniques of how to use the both concepts, each one in its context to better understand the divergence.
Compare the Interface nature to the class nature:
The interface is a member of a given namespace witch can integrate only member's signatures in its structure and I mean by members signatures those following: methods, properties, indexers and events that contain zero implementation. An interface core can be represented as follow.
namespace myProject <?xml:namespace prefix = o ns = "urn:schemas-microsoft-com:office:office" />
{
interface IPerson { }
}
When defining an interface, we should always precede its significant name by an "I" so that others developers understand that this member is an interface, this is the convention. Say, that you want to define an interface called Person; you should precede the word person by "I" so that the interface name will be IPerson. The .Net environment provides a huge number of predefined or built in interfaces that you can explore using the objects browser.
Figure 1
To do so, select View menu, select the object browser menu item then type the name of your interface and confirm the research process. Generally interfaces are represented within .Net related IDE by this symbol . All members are presented without the body '{// implementation}' within an interface witch is a comment characteristic that shares with an abstract class. A class implements an interface and doesn't inherit it as special kind of implementation is used within inheritance, it's called overriding given class members. The divergence could be represented as follow:
Figure 2
A given class can inherit an abstract class by implementing exclusively all its members and by overriding its methods totally or partially, if all members are overridden then you can instantiate this class and use it as normally in your code but if members are partially overridden, I mean, exactly when some of those members are left without any implementation then you can not instantiate your derived class. In this case you have to create another class that inherits the first derived class and overrides the rest of the members those have not been overridden yet. Given that the abstract class and the rest of classes include both implementation and definition, interfaces include only the definition.
public abstract class Mother
{
public abstract void Method1(int i);
public abstract void Method2(string i);
}
Remark the existence of the keyword abstract that marks both of the class and each method. Witch indicates that the class is a Base class that couldn't be instantiated directly. If you try to instantiate it, you'll receive an error.
Mother x = new Mother();
Figure 3
At the members level abstract keyword marks that the given member hasn't been implemented yet, it's automatically supposed as virtual .It has to be implemented in a derived class. The abstract member has to be only declared within an abstract class; otherwise, an error will be generated at the run time
Figure 4
You can create a class's hierarchy through this mechanism:
public abstract class Mother
{
public Mother()
{ }
public abstract string x
{
get;
set;
}
}
public class Daughter : Mother
{
public Daughter() : base()
{
//Some implementations here
}
private string _x;
public override string x
{
get
{
return _x;
}
set
{
_x = value;
}
}
}
Also interfaces could be wrapped in a hierarchy structure like classes but you can not talk about inheritance such as in classes case including the abstract classes, Of Corse.
Interfaces can extend and/or compose other interfaces. A given interface extends a second interface by adding new members like in the IEnumerator and the IDictionaryEnumerator built in interfaces case. In this particular case, the IEnumerator interface is extended by the IDictionaryEnumerator.
interface IEnumerator
{
bool MoveNext();
object Current
{
get;
}
void Reset();
}
The IDictionaryEnumerator extends the IEnumerator b y some others additional elements
interface IDictionaryEnumerator : IEnumerator
{
//IEnumerator members....
DictionaryEntry Entry
{
get;
/*it's read only*/
}
DictionaryEntry Entry
{
get;
/*it's read only*/
}
object value
{
get;
}
object key
{get;}
}
Interfaces can compose or aggregate other interfaces such in the IEnumearble and IEnumerator case. In this particular situation the relationship between the both built in interfaces is an aggregation because IEnumerator could be used independently.
interface IEnumerator
{
bool MoveNext();
object Current
{ get;}
void Reset();
}
interface IEnumerable
{
IEnumerator GetEnumerator();
}
As you remark, at the contrast of the classes including the abstract classes, the interfaces couldn't contain fields.
interface IEnumerator
{
bool MoveNext();
object Current;
//<- Genarates error at the runtime!! void Reset();
}
This interface presentation generates an error at the run time.
Figure 5
At the other hand, an interface has never to be instantiated like abstract classes because this generates the same error as instantiate an abstract class so be aware.
IPerson OPerson = new IPerson();
Figure 6
Generally interfaces aren't useful except that they are already implemented by other classes.
The interface members shouldn't be marked with an access modifier within an interface core such as public, private and so forth like in an abstract class or a derived class context, because it causes an error.
Figure 7
Only classes are able to use access modifiers. The class members access is possible throw the class instance or via using static keyword to mark members of a given class, something that is not tolerated within an interface context. I mean the keyword static has never to be used within an interface context either to mark interface members as static or to mark the interface it self as static.
There are two techniques to access interface members.
First technique:
Suppose that you have class Human that implements IHominid. The last one is composed by the following members.
public interface IHominid
{
string Category
{
get;
set;
}
int Height
{
get;
set;
}
int Weight
{
get;
set;
}
byte Sex
{
get;
set;
}
uint age
{
get;
set;
}
bool Concient();
}
Now as you implement the Human class, mark all interface members within the class core as public, it is allowed within the class core but not inside the interface core. As they marked as public, they belong now to the class members collection. You can access them through the class instances.
public class Human : IHominid
{
public Human()
{ Console.WriteLine("I'm human"); }
public Human(string FirstName, string LastName)
{
Console.WriteLine("I'm human");
this.FirstName = FirstName;
this.LastName = LastName;
}
public string FirstName;
public string LastName;
public bool HasAjob(bool Confirmation)
{
if (Confirmation)
{ return true; }
else
{ return false; }
}
public bool IsMarried(bool Confirmation)
{
if (Confirmation)
{ return true; }
else
{ return false; }
}
#region IHominid Members
private string _Category;
public string Category
{
get
{
return _Category;
}
set
{
_Category = value;
}
}
private int _Height;
public int Height
{
get
{
return _Height;
}
set
{
_Height = value;
}
}
private int _Weight;
public int Weight
{
get
{
return _Weight;
}
set
{
_Weight = value;
}
}
private byte _Sex;
public byte Sex
{
get
{
return _Sex;
}
set
{
_Sex = value;
}
}
private uint _age;
public uint age
{
get
{
return _age;
}
set
{
_age = value;
}
}
public bool Concient()
{
return true;
}
#endregion
}
Now, suppose that both of Human and IHominid define a method with same name, to avoid the potential conflict, you can use the second technique.
Second technique:
Say that both Human and IHominid define a same name method HasAJob () each, the class method returns a positive response while the interface method returns a negative response.
public interface IHominid
{
string Category { get; set;}
int Height { get; set;}
int Weight { get; set;}
byte Sex { get; set;}
uint age { get; set;}
bool Concient();
void HasAjob();
}
And
public class Human: IHominid
{
public Human()
{
Console.WriteLine("I'm human"); }
public Human(string FirstName, string LastName)
{
Console.WriteLine("I'm human");
this.FirstName = FirstName;
this.LastName = LastName;
}
public string FirstName;
public string LastName;
public void HasAjob()
{
Console.WriteLine("Yes, I have a job.");
Console.Read();
}
#region IHominid Members
private string _Category;
/* The HasAjob method has to be explicitly implemented in such context
* in order to have two distinct HasJob() method that means that the full name has to be used as bellow*/
void IHominid.HasAjob()
{
Console.WriteLine("I'm jobless.");
Console.ReadLine();
}
# end region
}
In such case, you have to implement the interface method using an explicit implementation in order to distinguish it from the class method, I mean you have to use the full method name including the interface name like this void IHominid.HasAjob (), also you shouldn't mark this interface member as public or as any other access mode, otherwise, the compiler will use the class method instead. Given that the both same named methods don't return the same result, implement the class program as so:
First, have access to the class method through this code:
class Program
{
public static void Main(string[] args)
{
Console.WriteLine("Hello World!");
Human me = new Human("Bejaoui","Bechir");
me.HasAjob(); // TODO: Implement Functionality Here
Console.Write("Press any key to continue . . . ");
Console.ReadKey(true); Console.Beep();
}
}
Then, have access to the interface method via this code:
class Program
{
public static void Main(string[] args)
{
Console.WriteLine("Hello World!");
Human me = new Human("Bejaoui","Bechir");
IHominid meAgain = (IHominid)me; meAgain.HasAjob(); // TODO: Implement Functionality Here
Console.Write("Press any key to continue . . . ");
Console.ReadKey(true); Console.Beep();
}
}
At last but not least, an abstract class can inherit only from one another class but a base interface can extend multiple base interfaces at once.
You shouldn't miss the What really it differs an Interface from a class: Part II.