Introduction
In this article along with the demo Code I will discuss Interfaces versus Abstract classes. The concept of Abstract classes and Interfaces is a bit confusing for beginners of Object Oriented programming. Therefore, I am trying to discuss the theoretical aspects of both the concepts and compare their usage. And finally I will demonstrate how to use them with C#.
About Abstract Class :
Abstract class is a class that contain complete(complete/Body) and abstract (Incomplete/Definition) both type of member and it can not be instantiated, Abstract classes are one of the essential behaviors provided by dotnet.
So the question is why we need a class that cannot be instantiated? An abstract class is only to be sub-classed (inherited from). In other words, it only allows other classes to inherit from it but cannot be instantiated.
When we create an abstract class, we are creating a base class that might have one or more completed methods but at least one or more methods are left uncompleted and declared abstract
. If all the methods of an abstract class are uncompleted then it is same as an interface. The purpose of an abstract class is to provide a base class definition for how a set of derived classes will work and then allow the programmers to fill the implementation in the derived classes.
Key Points:
- Abstract class can have property, Data fields ,Methods (complete / incomplete) both.
- If method or Properties define in abstract keyword that must override in derived class.(its work as a tightly coupled functionality)
- If define abstract keyword for method or properties in abstract class you can not define body of method and get/set value for properties and that must override in derived class.
- Abstract class does not support multiple inheritance.
- Abstract class contains Constructors.
- An abstract class can contain access modifiers for the subs, functions, properties.
- Only Complete Member of abstract class can be Static.
Advantage:
- It is a kind of contract that forces all the subclasses to carry on the same hierarchies or standards.
- If various implementations are of the same kind and use common behavior or status then abstract class is better to use.
- If we add a new method to an abstract class then we have the option of providing default implementation and therefore all the existing code might work properly.
- Its allow fast execution than interface.(interface Requires more time to find the actual method in the corresponding classes.)
- It can use for tight and loosely coupling.
About Interface :
An interface is not a class. It is an entity that is defined by the word Interface. Interface is a type which contains only the signatures of methods, delegates or events, it has no implementation, Implementation of the methods is done by the class that which implements the interface. In other words, just the definition of the methods without the body.
As one of the similarities to Abstract class, it is a contract that is used to define hierarchies for all subclasses or it defines specific set of methods and their arguments. The main difference between them is that a class can implement more than one interface but can only inherit from one abstract class. Since C# doesn’t support multiple inheritance, interfaces are used to implement multiple inheritance.
Interface is a contract that defines the signature of the functionality. So if a class is implementing a interface it says to the outer world, that it provides specific behavior. Example if a class is implementing ‘Idisposable’ interface that means it has a functionality to release unmanaged resources.
Key Points:
- Interface can have property, Methods (incomplete/signature only) but not Data fields.
- If method or Properties define in Interface that must used in implemented class.(its work as a tightly coupled functionality) no need to use New,override keyword for access data member from interface.
- Interface can not define body of method and get/set value for properties and that must used in implemented class.
- Interface does provide facility for multiple inheritance.
- Interface can not contains Constructors.
- Interface can not access modifiers for the functions, properties its by default public only.
- Member of interface can not be Static.
Advantage:
- If various implementations only share method signatures then it is better to use Interfaces.
- Interfaces are used to define the peripheral abilities of a class. In other words both Human and Vehicle can inherit from a IMovable interface.
Demo Code:
MyCar Abstract class:-
using System;
namespace AbstractInterfaceExample
{
public abstract class MyCar
{
//Abstract class not define fields.
protected string _colour;
protected string _brand;
protected string _launchingYear;
protected double _prise;
//define Properties as abstract
public abstract string Colour
{
get;
set;
}
public abstract string Brand
{
get;
set;
}
public abstract string LaunchingYear
{
get;
set;
}
public abstract double Prise
{
get;
set;
}
//methods with defination
public String GetColour(string carNameName)
{
switch (carNameName.ToLower().Trim())
{
case "alto":
Colour = "Red";
break;
case "city":
Colour = "Black";
break;
default:
Colour = "Colour no found";
break;
}
return Colour;
}
public String GetBrand(string carNameName)
{
switch (carNameName.ToLower().Trim())
{
case "alto":
Brand = "MarutiSuzuki";
break;
case "city":
Brand = "Honda";
break;
default:
Brand = "Does not found brand.";
break;
}
return Brand;
}
public String GetLaunchingYear(string carNameName, string brandName)
{
if (carNameName.ToLower().Trim() == "alto" && brandName.ToLower().Trim() == "marutisuzuki")
{ LaunchingYear = "1st Jan 2000"; }
else if (carNameName.ToLower().Trim() == "city" && brandName.ToLower().Trim() == "honda")
{ LaunchingYear = "18st Oct 2005"; }
else
{ LaunchingYear = "Does not found Launching Year."; }
return LaunchingYear;
}
//Error:'AbstractInterfaceExample.MyCar.GetPrise()' must declare a body because it is not marked abstract, extern, or partial
//C:\Users\paa99221\Desktop\Pradeep\example\AbstractInterfaceExample\AbstractInterfaceExample\MyCar.cs 81 23 AbstractInterfaceExample
//public double GetPrise(string carNameName, string brandName);
//abstract method that allow to define without body of the class.
public abstract double GetPrise(string carNameName, string brandName);
}
}
IMyCar Interface:-
using System;
/*******************************************************
* Interface for MyCar
* *****************************************************/
namespace AbstractInterfaceExample
{
interface IMyCar
{
//just signature of the properties.
//Interface can not define fields.
string Colour{ get; set; }
string Brand { get; set; }
string LaunchingYear { get; set; }
double Prise { get; set; }
//cannot have defination of method only define signature of method.
// cannot have access specifier by default public.
// cannot have virtual key word for override the method.
String GetColour(string carNameName);
String GetBrand(string carNameName);
String GetLaunchingYear(string carNameName,string brandName);
//Error 1 'AbstractInterfaceExample.IMyCar.GetPrise(string, string)': interface members cannot have a definition
//C:\Users\paa99221\Desktop\Pradeep\example\AbstractInterfaceExample\AbstractInterfaceExample\IMyCar.cs 21 16 AbstractInterfaceExample
//double GetPrise(string carNameName, string brandName) { }
double GetPrise(string carNameName, string brandName);
}
}
DemoAbstractExample class inherit abstract class:-
derived Class inherit from base abstract MyCar.
//Inherit abstract class MyCar
public class DemoAbstractExample:MyCar
{
//uses all the properties of the Abstract class therefore no
//properties or fields here.
//Override Properties using override keyword
public override string Colour
{
get { return _colour; }
set { _colour = value; }
}
public override string Brand
{
get { return _brand; }
set { _brand = value; }
}
public override string LaunchingYear
{
get { return _launchingYear; }
set { _launchingYear = value; }
}
public override double Prise
{
get { return _prise; }
set { _prise = value; }
}
//common methods that are implemented in the abstract class
//use new keyword for override the method which is not defined
//'abstract' or 'virtual' keyword in base class (MyCar class)
public new String GetColour(string carNameName)
{
return base.GetColour(carNameName);
}
public new String GetBrand(string carNameName)
{
return base.GetBrand(carNameName);
}
public new String GetLaunchingYear(string carNameName, string brandName)
{
return base.GetLaunchingYear(carNameName, brandName);
}
//use override keyword for override the method which is defined
//'abstract' keyword in base class (MyCar class)
public override double GetPrise(string carNameName, string brandName)
{
if (carNameName.ToLower().Trim() == "alto" && brandName.ToLower().Trim() == "marutisuzuki")
{ Prise = 350000.00; }
else if (carNameName.ToLower().Trim() == "city" && brandName.ToLower().Trim() == "honda")
{ Prise = 1050000.00; }
else
{ Prise = 0.00; }
return Prise;
}
}
DemoInterfaceExample class impliment interface:-
Class implements interface IMyCar.
//impliment interface IMyCar
public class DemoInterfaceExample:IMyCar
{
//fields are defined here.
protected string _colour;
protected string _brand;
protected string _launchingYear;
protected double _prise;
//set Properties values
public string Colour //Property name present in Interface
{
get { return _colour; }
set { _colour = value; }
}
public string Brand
{
get { return _brand; }
set { _brand = value; }
}
public string LaunchingYear
{
get { return _launchingYear; }
set { _launchingYear = value; }
}
public double Prise
{
get { return _prise; }
set { _prise = value; }
}
//implementation the Interface entity (methods).
public string GetColour(string carNameName)
{
switch (carNameName.ToLower().Trim())
{
case "alto":
Colour = "Red";
break;
case "city":
Colour = "Black";
break;
default:
Colour = "Colour not found.";
break;
}
return Colour;
}
public String GetBrand(string carNameName)
{
switch (carNameName.ToLower().Trim())
{
case "alto":
Brand = "MarutiSuzuki";
break;
case "city":
Brand = "Honda";
break;
default:
Brand = "Does not found brand.";
break;
}
return Brand;
}
public String GetLaunchingYear(string carNameName, string brandName)
{
if (carNameName.ToLower().Trim() == "alto" && brandName.ToLower().Trim() == "marutisuzuki")
{ LaunchingYear = "1st Jan 2000"; }
else if (carNameName.ToLower().Trim() == "city" && brandName.ToLower().Trim() == "honda")
{ LaunchingYear = "18st Oct 2005"; }
else
{ LaunchingYear = "Does not found Launching Year."; }
return LaunchingYear;
}
public double GetPrise(string carNameName, string brandName)
{
if (carNameName.ToLower().Trim() == "alto" && brandName.ToLower().Trim() == "marutisuzuki")
{ Prise = 350000.00; }
else if (carNameName.ToLower().Trim() == "city" && brandName.ToLower().Trim() == "honda")
{ Prise = 1050000.00; }
else
{ Prise = 0.00; }
return Prise;
}
}
Main class:-
main class.
class Program
{
//main method
static void Main(string[] args)
{
DemoAbstractExample DAE = new DemoAbstractExample();
DemoInterfaceExample DIE = new DemoInterfaceExample();
Console.WriteLine("press 1 for Absract class and 2 for interface.");
int choice = Convert.ToInt16(Console.ReadLine());
if (choice == 1)
{
Console.WriteLine("I am from Abstract Class..");
Console.WriteLine("Enter Car name for get colour..");
Console.WriteLine("Car colour is: {0}", DAE.GetColour(Console.ReadLine().ToString()));
Console.WriteLine("Enter Car name for get Manufacturer..");
Console.WriteLine("Car belongs to: {0}", DAE.GetBrand(Console.ReadLine().ToString()));
Console.WriteLine("Enter Car name and Brand for get Launching Year..");
Console.WriteLine("Car has been Launched in: {0}", DAE.GetPrise(Console.ReadLine().ToString(), Console.ReadLine().ToString()));
Console.WriteLine("Enter Car name and Brand for get prise of the car..");
Console.WriteLine("Prise of car is: {0}", DAE.GetPrise(Console.ReadLine().ToString(), Console.ReadLine().ToString()));
}
else
{
Console.WriteLine("I am from Interface..");
Console.WriteLine("Enter Car name for get colour..");
Console.WriteLine("Car colour is: {0}", DAE.GetColour(Console.ReadLine().ToString()));
Console.WriteLine("Enter Car name for get Manufacturer..");
Console.WriteLine("Car belongs to: {0}", DAE.GetBrand(Console.ReadLine().ToString()));
Console.WriteLine("Enter Car name and Brand for get Launching Year..");
Console.WriteLine("Car has been Launched in: {0}", DAE.GetPrise(Console.ReadLine().ToString(), Console.ReadLine().ToString()));
Console.WriteLine("Enter Car name and Brand for get prise of the car..");
Console.WriteLine("Prise of car is: {0}", DAE.GetPrise(Console.ReadLine().ToString(), Console.ReadLine().ToString()));
}
//retain the scree.
Console.ReadLine();
}
In the above examples, I have explained the differences between an abstract class and an interface. I have also implemented a demo project which uses both abstract class and interface and shows the differences in their implementation.