Tuesday 15 December 2020

Abstract Class vs Interface- Details Concepts - Xamarin Developer

MSDN Library, the "abstract" keyword indicates that the thing has a missing or incomplete implementation and must be completed by others.

The abstract keyword can be used with classes, methods, properties, indexers and events. If we use the abstract keyword with a class, it indicates that the class is intended to be a base class and can have abstract methods (ideas) that must be implemented in a derived class (physical existence).

An abstract class is a special kind of class that has no implementation. 

It cannot be instantiated. Its implementation logic is provided by the classes that derive from it. 

It can have both abstract as well as non-abstract methods.


It is not compulsory to have only abstract methods in an abstract class. We can also have an abstract class with only non-abstract methods.

With an Abstract Class, we can provide some kind of default functionality for all derived classes to extend from. This is useful to avoid code duplication in many cases.

Lets Understand this with example :

Suppose we are defining an iPhone class for Apple and then inheriting it to iPhone5 and iPhone5s subclasses. Practically we don't want an object of an iPhone class since we first need to know the model of iPhone. So, the iPhone class should be an abstract class that contains some predefined functions like Call() and SMS() for all iPhone models to share . We can also add abstract methods like Model() and Color() into the iPhone class that must be implemented by all the subclasses inheriting iPhone. The main advantage of this approach is, whenever we inherit the iPhone class into a derived class, say iPhone5s, we need not define the Call() and SMS() methods again. We just need to implement the abstract methods and we are good to go. It helps to provide default functionality in all the derived classes and also avoids code duplication.

Abstract classes are also useful in the case of modifications to the project. If you plan on updating the base class in your project, it is better to make the class abstract. Because you can define a functionality in an abstract base class and automatically all the inheriting classes will have the same functionality without disturbing the hierarchy.

By default, it gives a class named Program with Main method in it for code execution. We can create an abstract class by putting the keyword abstract before a class definition as follows:

  1. using System;   
  2.   
  3. namespace AbstractClassDemo   
  4. {   
  5.     abstract class iPhone { } //Definition of an Abstract Class   
  6.     class Program   
  7.     {   
  8.         static void Main(string[] args) { }   
  9.     }   
  10. }  

The code above defines a simple abstract class. However, we cannot create an object/instance of abstract class. It gives us an error straightaway.

  1. using System;   
  2.   
  3. namespace AbstractClassDemo   
  4. {   
  5.     abstract class iPhone { }   
  6.     class Program   
  7.     {   
  8.         static void Main(string[] args)   
  9.         {   
  10.             //Instantiation of an Abstract Class   
  11.             iPhone iphone = new iPhone();   
  12.         }   
  13.     }   
  14. }   

Error Message in Visual Studio

So, we need to define members in it that can be in derived classes. We can define abstract as well as non-abstract members in an abstract class. An abstract class with non-abstract method is as follows:

  1. using System;   
  2.   
  3. namespace AbstractClassDemo   
  4. {   
  5.     abstract class iPhone   
  6.     {   
  7.         //Non-Abstract Method   
  8.         public void Call()   
  9.         {   
  10.             Console.WriteLine("Call Method: This method provides Calling features");   
  11.         }   
  12.     }  
  13.     class Program   
  14.     {   
  15.         static void Main(string[] args)   
  16.         {   
  17.         }   
  18.     }   
  19. }   

The iPhone class shows a non-abstract method Call() that provides the default functionality to all sub classes that are derived from it. We cannot create an object of iPhone class but we can still use the Call() method in derived classes. 

  1. using System;   
  2.   
  3. namespace AbstractClassDemo   
  4. {   
  5.     abstract class iPhone   
  6.     {   
  7.         //Non-Abstract Method   
  8.         public void Call()   
  9.         {   
  10.             Console.WriteLine("Call Method: This method provides Calling features");   
  11.         }   
  12.     }   
  13.       
  14.     class Program: iPhone   
  15.     {   
  16.         static void Main(string[] args)   
  17.         {   
  18.             //Instance Creation of Derived Class   
  19.             Program program = new Program();   
  20.             program.Call();   
  21.             Console.ReadKey();   
  22.         }   
  23.     }   
  24. }    

Output using Abstract Method

The code above shows a simple inheritance of an abstract class into a concrete class. 

(A concrete class is a class that has an implementation for all of its methods. They cannot have any unimplemented methods. It can also extend an abstract class or implement an interface as long as it implements all their methods. It is a complete class and can be instantiated.

In other words, we can say that any class which is not abstract is a concrete class.

Necessary condition for a concrete class: There must be an implementation for each and every method.)

This type of inheritance can also be done by two concrete classes. So, why do we want an abstract class?

The answer is, to provide default functionality and to add abstract methods. The iPhone class is inherited by all iPhone models, so the Call() method is required in all the models. It is better to define a Call() method in the abstract class so that each derived class can have the Call() method automatically and doesn't need to define it again.

Each iPhone model has some of its own features like Color and Model. So, we can define a contract in an abstract class that must be implemented in derived classes as per their requirements. These types of contracts are called abstract methods and in this example is Model(). Abstract methods only have a signature and no implementation. It is a kind of contract that forces all the subclasses to implement it.

Like the abstract class, abstract methods are also declared using the abstract keyword. It may be noted that an abstract method cannot be private or it gives an error:

  1. using System;   
  2.   
  3. namespace AbstractClassDemo   
  4. {   
  5.     abstract class iPhone   
  6.     {   
  7.         //Non-Abstract Method   
  8.         public void Call()   
  9.         {   
  10.             Console.WriteLine("Call Method: This method provides Calling features");   
  11.         }   
  12.       
  13.         //Abstract Method kept as Private   
  14.         abstract void Model();   
  15.     }   
  16.   
  17.     class Program   
  18.     {   
  19.         static void Main(string[] args)   
  20.         {   
  21.         }   
  22.     }   
  23. }  

If we compile this code, it gives us an error:

Error while creating abstract private

So, the correct way to declare an abstract method is as follows:

  1. using System;   
  2.   
  3. namespace AbstractClassDemo   
  4. {   
  5.     abstract class iPhone   
  6.     {   
  7.         //Non-Abstract Method   
  8.         public void Call()   
  9.         {   
  10.             Console.WriteLine("Call Method: This method provides Calling features");   
  11.         }   
  12.   
  13.         //Abstract Method   
  14.         public abstract void Model();   
  15.     }   
  16.   
  17.     class Program   
  18.     {   
  19.         static void Main(string[] args)   
  20.         {   
  21.         }   
  22.     }   
  23. }  

The Model() method enforces all the derived classes to implement it. We can define a new concrete class iPhone5s that inherits the abstract class iPhone and provides the definition of Model() method.

  1. using System;   
  2.   
  3. namespace AbstractClassDemo   
  4. {   
  5.     abstract class iPhone   
  6.     {   
  7.         //Non-Abstract Method   
  8.         public void Call()   
  9.         {   
  10.             Console.WriteLine("Call Method: This method provides Calling features");   
  11.         }   
  12.       
  13.         //Abstract Method   
  14.         public abstract void Model();   
  15.     }   
  16.   
  17.     class iPhone5s: iPhone   
  18.     {   
  19.     }   
  20.   
  21.     class Program   
  22.     {   
  23.         static void Main(string[] args)   
  24.         {   
  25.         }   
  26.     }   
  27. }  

If we don't provide the definition of the abstract method in the derived class, it throws an error: 

Implement Abstract Member

Ok. Let's provide the definition of Model() method in the derived class:

  1. using System;   
  2.   
  3. namespace AbstractClassDemo   
  4. {   
  5.     abstract class iPhone   
  6.     {   
  7.         //Non-Abstract method   
  8.         public void Call()   
  9.         {   
  10.             Console.WriteLine("Call Method: This method provides Calling features");   
  11.         }   
  12.       
  13.         //Abstract Method   
  14.         public abstract void Model();   
  15.     }   
  16.   
  17.     class iPhone5s: iPhone   
  18.     {   
  19.         //Abstract Method Implementation   
  20.         public void Model()   
  21.         {   
  22.             Console.WriteLine("Model: The model of this iPhone is iPhone5s");   
  23.         }   
  24.     }   
  25.   
  26.     class Program   
  27.     {   
  28.         static void Main(string[] args)   
  29.         {   
  30.         }   
  31.     }   
  32. }   

Now we have defined the Model() method in the class iPhone5s. Let's compile the code above. Whoa, it gives us an error plus a warning.

Inheriting Abstarct Member

The error says "The Model() method is not implemented in derived class". It seems fair since we aren't overriding the base method, which means the compiler believe that there is no implementation of the Model() method in the derived class.
It also gives us a warning  "To make the current member override that implementation, add the override keyword, otherwise add the new keyword". It means that the compiler is confused about the Model() method we declared in the iPhone5s class.

If you want to override the base class method in derived class, use the override keyword with the method and if your derived class method is not related in any way with the base class method, use the new keyword. The new keyword signifies that the method in the derived class has nothing to do with the base class method.

In our case, we want the base class method to be defined in the derived class. So, we use the override keyword. Also, we can add local methods in the iPhone5s class:

  1. using System;   
  2.   
  3. namespace AbstractClassDemo   
  4. {   
  5.     abstract class iPhone   
  6.     {   
  7.         //Non-Abstract Method   
  8.         public void Call()   
  9.         {   
  10.             Console.WriteLine("Call Method: This method provides Calling features");   
  11.         }   
  12.       
  13.         //Abstract Method   
  14.         public abstract void Model();   
  15.     }   
  16.   
  17.     class iPhone5s: iPhone   
  18.     {   
  19.         //Abstract Method Implementation   
  20.         public override void Model()   
  21.         {   
  22.             Console.WriteLine("Model: The model of this iPhone is iPhone5s");   
  23.         }   
  24.       
  25.         //Derived Class Local Method   
  26.         public void LaunchDate()   
  27.         {   
  28.             Console.WriteLine("Launch Date: This iPhone was launched on 20- September-2013");   
  29.         }   
  30.     }   
  31.       
  32.     class Program   
  33.     {   
  34.         static void Main(string[] args)   
  35.         {   
  36.               
  37.         }   
  38.     }   
  39. }   

All good. Let's use the iPhone5s class that now has methods from the abstract class as well as its own methods.

  1. using System;   
  2.   
  3. namespace AbstractClassDemo   
  4. {   
  5.     abstract class iPhone   
  6.     {   
  7.         public void Call()   
  8.         {   
  9.             Console.WriteLine("Call Method: This method provides Calling features");   
  10.         }      
  11.         public abstract void Model();   
  12.     }   
  13.   
  14.     class iPhone5s: iPhone   
  15.     {  
  16.         public override void Model()   
  17.         {   
  18.             Console.WriteLine("Model: The model of this iPhone is iPhone5s");   
  19.         }   
  20.   
  21.         public void LaunchDate()   
  22.         {   
  23.             Console.WriteLine("Launch Date: This iPhone was launched on 20-September-2013");   
  24.         }   
  25.     }   
  26.   
  27.     class Program   
  28.     {   
  29.         static void Main(string[] args)   
  30.         {   
  31.             iPhone5s iphone5s = new iPhone5s();   
  32.             iphone5s.Call();   
  33.             iphone5s.Model();  
  34.             iphone5s.LaunchDate();   
  35.             Console.ReadKey();   
  36.         }   
  37.     }   
  38. }   

If we run the code, it works perfectly.

Code Output

In the preceding example, I explained how to use an abstract class in a very simple way. We are able to implement an abstract class and its abstract members into a concrete class. The following are some key points to be remembered when working with abstract classes.

Key Points

  1. We cannot create an object of Abstract Class but we can create a reference of it.
    1. using System;   
    2.   
    3. namespace AbstractClassDemo   
    4. {   
    5.     abstract class absClass { }   
    6.     class Program   
    7.     {   
    8.         public static void Main(string[] args)   
    9.         {   
    10.             //We can't do this   
    11.             //absClass cls = new absClass();   
    12.             //We can do this   
    13.             absClass cls;   
    14.         }   
    15.     }   
    16. }   
  2. An inheritance between abstract to abstract classes is possible. We don't need to implement abstract methods of the base abstract class into a derived abstract class. We can implement it later in concrete classes.
    1. using System;   
    2.   
    3. namespace AbstractClassDemo   
    4. {   
    5.     abstract class absClassA   
    6.     {   
    7.         //Abstract Method   
    8.         public abstract void SomeMethod();   
    9.     }   
    10.   
    11.     abstract class absClassB: absClassA //Abstract to Abstract Inheritance   
    12.     {   
    13.     }   
    14.   
    15.     class Program: absClassB   
    16.     {   
    17.         public override void SomeMethod()   
    18.         {   
    19.             //Some Implementation Here   
    20.         }   
    21.   
    22.         public static void Main(string[] args)   
    23.         {   
    24.         }   
    25.     }   
    26. }  
  3. An abstract class can never be sealed or static.
     
  4. An abstract class can have abstract as well as non abstract methods.
     
  5. The abstract keyword can be used with class, methods, properties, indexers and events.
     
  6. Abstract members can only be declared inside an abstract class.
     
  7. An abstract member cannot be static or private.
     
  8. An abstract method cannot be marked virtual.
     
  9. A concrete class cannot inherit more than one abstract class, in other words multiple Inheritance is not possible.
     
  10. Without an abstract class, we cannot implement the Template Method Pattern.


What an interface is


In the real world, an interface means a medium to interact with something. To be precise, it's a point where two systems, subjects, organizations and so on meet and interact. There are a few rules for the interaction to be done. Suppose you are going for an interview of Programmer Profile. The interview is only possible if the interviewer and you speak the same language. Moreover, you and the interviewer have the same skill set of programming languages to discuss upon.

Similarly, in the programming world, an interface means a contract to interact with multiple code modules. If a class wants to communicate with an interface, it must implement it and define its members. Consider it like the interviewer's question and you need to answer it correctly, if you want the job.

The MSDN Library defines the interface like a pure abstract class. An interface contains only the signatures of methods, properties, events, or indexers. It has no implementation of its own and can only be implemented by a class or a struct. Any of the two that implement the interface must provide the definitions to members specified in the interface. It is like a contract for all the derived classes to follow.

An interface is declared using the interface keyword. interface members are implicitly public and abstract, so we cannot prefix any access modifiers to it. An interface cannot contain fields, constant members, constructors, destructors and static members.

Why we need an interface


An interface is not a class. It contains only method signatures. It has no implementation on its own and cannot be instantiated. Its implementation logic is provided by the classes that derived from it. An interface is mostly considered to be a pure abstract class. However, there is the advantage of using an interface over an abstract class; that is "Multiple Inheritance Support". In C#, two classes (either abstract or concrete) cannot be inherited by the same derived class. It causes ambiguity in the derived class if both have the same method signature. We can do multiple inheritance in C# using interfaces.

An interface plays a vital role in the Service Oriented Architecture (SOA). In WCF, we use interfaces to define Service Contracts. A single class can implement any number of Service Contract Interfaces. It is generally accepted as the best practice to do so. However, we can also use classes for Service Contracts.

Most of the Design Patterns and Principles are based on interfaces rather than class inheritance. Some of the examples are Builder Design Pattern, Factory Pattern, Interface Segregation Principle and so on.

How to define an interface


Suppose we need to define a class for a Smart Phone. The class can have members like OS, AppStore and Call. The Smartphone can be either Android based or iOS based and cannot be both. There is no common functionality between an Android and iOS Smartphone, so we don't need to provide any default functionality. One approach is to make the SmartPhone class abstract and also all its members abstract. This approach works fine and several concrete classes like Samsung, Apple, HTC can inherit from it.

Now, after a few days Apple wants to add a Touch ID feature to its Smartphone. You can add TouchID as an abstract method in your abstract base class SmartPhone. But what if HTC doesn't want that feature and neither does Samsung? So, the TouchID method cannot be placed inside the abstract class SmartPhone. An alternative is to define another abstract class Features and add the TouchID method to it. This is also a bad idea since C# doesn't support inheritance of multiple classes (abstract or concrete) into a derived class.

In this situation, an interface is useful and plays a vital role in solving the problem. An interface provides only the method definitions, just like an abstract class, but can be useful in multiple inheritances. You can make the Features class an interface and add the TouchID method to it. It provides only the method signature and whichever class inherits it can implement it in its own way. It is also completely valid for a class to inherit more than one interface in C#. Also, we can make the SmartPhone class an interface instead of an abstract class. It is better instead of making a pure abstract class, we can use interfaces.

Note: The example is not a best one, but I think it gets the point across. It is just for the sake of understanding interfaces.

Let us consider the example discussed above and create a Console Application for it. Open Visual Studio and add a new console project as "InterfaceDemo". 

console application

By default, it gives a class named Program with a Main method in it for code execution. Let's create an abstract class SmartPhone and define OS and AppStore abstract methods in it. We can create an abstract class by putting the keyword "abstract" before a class definition. If you're not familiar with abstract classes, please go to the Part 1 of this series.

  1. using System;   
  2.    
  3. namespace InterfaceDemo    
  4. {   
  5.      //Abstract Class SmartPhone with only abstract methods in it    
  6.      abstract class SmartPhone    
  7.      {    
  8.          public abstract void OS();    
  9.          public abstract void AppStore();    
  10.      }    
  11.    
  12.      class Program    
  13.      {    
  14.         static void Main(string[] args)    
  15.         {    
  16.         }    
  17.      }    
  18. }   

Now define the concrete classes Apple and Samsung that inherits from Smartphone and provides the definitions to the abstract methods OS and AppStore.

  1. using System;   
  2.    
  3. namespace InterfaceDemo    
  4. {    
  5.       //Abstract Class SmartPhone with only abstract methods in it    
  6.       abstract class SmartPhone    
  7.       {   
  8.          public abstract void OS();   
  9.          public abstract void AppStore();    
  10.       }   
  11.    
  12.       class Apple : SmartPhone    
  13.       {   
  14.           public override void OS()    
  15.           {    
  16.             //Some Implementation Here    
  17.           }   
  18.    
  19.           public override void AppStore()    
  20.           {   
  21.              //Some Implementation Here    
  22.           }    
  23.        }    
  24.    
  25.        class Samsung: SmartPhone    
  26.        {   
  27.           public override void OS()    
  28.           {    
  29.               //Some Implementation Here    
  30.           }   
  31.    
  32.           public override void AppStore()    
  33.           {   
  34.               //Some Implementation Here    
  35.           }   
  36.        }   
  37.        
  38.        class Program    
  39.        {    
  40.           static void Main(string[] args)    
  41.           {    
  42.           }    
  43.        }    
  44. }   

If we compile the code now, it works fine. Our SmartPhone class is implemented by two different concrete classes Apple and Samsung and defined depending on them. Now, let us suppose Apple wants to provide TouchID features to its Smartphone. We can add another abstract method TouchID in the SmartPhone class and let Apple inherit it and implement it.

  1. using System;    
  2.    
  3. namespace InterfaceDemo    
  4. {    
  5.     //Abstract Class SmartPhone   
  6.     abstract class SmartPhone    
  7.     {    
  8.        public abstract void OS();    
  9.        public abstract void AppStore();    
  10.    
  11.        //TouchID method meant only for Apple Class   
  12.        public abstract void TouchID();    
  13.     }    
  14.    
  15.     class Apple : SmartPhone    
  16.     {    
  17.          public override void OS()    
  18.          {   
  19.             //Some Implementation Here    
  20.          }   
  21.    
  22.          public override void AppStore()    
  23.          {    
  24.              //Some Implementation Here    
  25.          }   
  26.    
  27.          //Implementing the TouchID feature    
  28.         public override void TouchID()    
  29.         {    
  30.             //Some Implementation Here    
  31.         }    
  32.     }    
  33.    
  34.     class Samsung: SmartPhone    
  35.     {    
  36.         public override void OS()    
  37.         {    
  38.              //Some Implementation Here    
  39.         }   
  40.    
  41.         public override void AppStore()    
  42.         {    
  43.               //Some Implementation Here    
  44.         }    
  45.     }   
  46.    
  47.     class Program    
  48.     {    
  49.        static void Main(string[] args) { }    
  50.     }   
  51. }   

The Apple class inherits the TouchID method and provides a definition to it. Let's compile the code now and see what happens.

error

It throws an error saying that the Samsung class doesn't implement the TouchID method. By the definition of abstract class, any class implements it must provide definitions to all its abstract members. The TouchID method is meant only for the Apple class and the Samsung class doesn't want to implement it. It clearly seems that our approach is wrong since the TouchID method cannot be placed in the SmartPhone abstract class.

An alternative approach is to define another abstract class Features and define the TouchID method to it. This approach seems fine since whatever class inherits Features can implement the TouchID method.

  1. using System;    
  2.    
  3. namespace InterfaceDemo    
  4. {    
  5.       //Abstract Class SmartPhone    
  6.       abstract class SmartPhone    
  7.       {   
  8.          public abstract void OS();   
  9.          public abstract void AppStore();    
  10.       }   
  11.    
  12.       //Abstract Class Features for TouchID method   
  13.       abstract class Features    
  14.       {   
  15.          public abstract void TouchID();    
  16.       }    
  17.    
  18.      //Apple Class inherits both SmartPhone and Features   
  19.       class Apple : SmartPhone, Features    
  20.       {   
  21.          public override void OS()   
  22.          {    
  23.             //Some Implementation Here    
  24.          }   
  25.            
  26.          public override void AppStore()    
  27.          {   
  28.              //Some Implementation Here    
  29.          }   
  30.    
  31.          //Implementation of TouchID method in Apple Class    
  32.          public override void TouchID()    
  33.          {   
  34.              //Some Implementation Here    
  35.          }   
  36.       }   
  37.    
  38.       class Samsung : SmartPhone    
  39.       {   
  40.          public override void OS()    
  41.          {    
  42.            //Some Implementation Here    
  43.          }    
  44.    
  45.          public override void AppStore()   
  46.          {   
  47.             //Some Implementation Here    
  48.          }    
  49.        }   
  50.    
  51.        class Program    
  52.       {   
  53.           static void Main(string[] args)    
  54.           {   
  55.           }    
  56.       }    
  57. }   

Let's compile the code and see what happens. 

compile error

It again throws an error saying we cannot have multiple base classes in a derived class. This is called Multiple Inheritance of classes and is not allowed in C#. So, our second approach also fails to implement the TouchID method. This is where an interface is useful and helps to solve the "Multiple Inheritance" issue in C#. We can define both the SmartPhone and Features as interfaces and let the classes implement them as they need to. We can also have more than one interface in a class. This is the only way to do multiple inheritance in C#. 

Let's re-create the same project using interfaces. We can create an interface using the keyword interface. It is considered a good practice to prefix "I" before the interface name, however the point is arguable and the choice is yours.

  1. using System;    
  2.    
  3. namespace InterfaceDemo    
  4. {   
  5.      interface ISmartPhone       //Definition of Interface    
  6.      {    
  7.          public void OS();    
  8.          public void AppStore();    
  9.      }    
  10.    
  11.      class Program    
  12.      {     
  13.         static void Main(string[] args)    
  14.         {    
  15.         }    
  16.      }    
  17. }   

We have defined the interface ISmartPhone with the method signatures OS and AppStore in it. If we compile the code now, it throws an error straightaway. 

error description

It says we cannot prefix public modifiers with method signatures. In fact, no access modifier is allowed with interface methods. Interface methods are implicitly public in C# because an interface is a contract meant to be used by other classes. Moreover, we must declare these methods as public in derived classes, when we provide implementations to these methods. Also, we cannot declare these methods as static.

  1. using System;    
  2.    
  3. namespace InterfaceDemo    
  4. {   
  5.      interface ISmartPhone //Definition of Interface   
  6.      {    
  7.          static void OS();    
  8.          static void AppStore();    
  9.      }    
  10.    
  11.      class Program    
  12.      {    
  13.         static void Main(string[] args)    
  14.         {    
  15.         }    
  16.      }    
  17. }   

If we compile the code, it again gives us an error.

error list

Let's define the interface methods without any access modifier and create a concrete class Apple that inherits the ISmartPhone interface and provides definitions to its members. 

  1. using System;    
  2.    
  3. namespace InterfaceDemo    
  4. {    
  5.     interface ISmartPhone    
  6.     {    
  7.          void OS();    
  8.          void AppStore();    
  9.     }    
  10.    
  11.     class Apple: ISmartPhone    
  12.     {    
  13.         //OS Method Implementation    
  14.         public void OS()    
  15.         {    
  16.                Console.WriteLine("OS Method: The OS of this Smartphone is iOS8");    
  17.         }    
  18.    
  19.         //AppStore Method Implementation    
  20.         public void AppStore()    
  21.         {    
  22.                Console.WriteLine("AppStore Method: The Application Store of this Smartphone is iTunes");    
  23.         }    
  24.      }    
  25.         
  26.      class Program    
  27.      {    
  28.        static void Main(string[] args)    
  29.        {    
  30.        }    
  31.      }    
  32. }  

An important point that should be noted here is that whenever we implement interface members in derived classes, the access modifier must always be public otherwise it throws an error. If we write a protected modifier instead of public to the OS method, the compiler throws an error.

  1. using System;    
  2.    
  3. namespace InterfaceDemo    
  4. {   
  5.       interface ISmartPhone    
  6.       {    
  7.            void OS();    
  8.            void AppStore();    
  9.       }    
  10.          
  11.       class Apple: ISmartPhone    
  12.       {    
  13.            //OS Method kept as Protected   
  14.            protected void OS()    
  15.            {    
  16.                Console.WriteLine("OS Method: The OS of this Smartphone is iOS8");    
  17.            }    
  18.    
  19.            //AppStore Method Implementation    
  20.            public void AppStore()    
  21.            {    
  22.                 Console.WriteLine("AppStore Method: The Application Store of this Smartphone is iTunes");    
  23.            }    
  24.        }    
  25.    
  26.        class Program    
  27.        {    
  28.           static void Main(string[] args) { }    
  29.        }    
  30. }   

In the code above, I replaced the access modifier of the OS method from public to protected. Let's compile the code and see what happens. 

compile error list

Yes, it throws an error saying that the Apple class cannot implement the OS method because it is not public. So, always keep your method implementations public in derived class. We can define another concrete class Samsung that also implements the interface ISmartPhone and provides definitions to its members.

  1. using System;   
  2.    
  3. namespace InterfaceDemo    
  4. {    
  5.      interface ISmartPhone     
  6.      {    
  7.          void OS();    
  8.          void AppStore();    
  9.      }    
  10.    
  11.      class Apple: ISmartPhone    
  12.      {    
  13.          //OS Method Implementation    
  14.          public void OS()    
  15.          {    
  16.             Console.WriteLine("OS Method: The OS of this Smartphone is iOS8");    
  17.          }    
  18.    
  19.          //AppStore Method Implementation    
  20.          public void AppStore()    
  21.          {    
  22.             Console.WriteLine("AppStore Method: The Application Store of this smartphone is iTunes");    
  23.          }    
  24.      }    
  25.    
  26.      class Samsung : ISmartPhone    
  27.      {    
  28.          //OS Method Implementation    
  29.          public void OS()    
  30.          {    
  31.             Console.WriteLine("OS Method: The OS of this smartphone is Android");    
  32.          }    
  33.    
  34.          //AppStore Method Implementation    
  35.          public void AppStore()    
  36.          {    
  37.             Console.WriteLine("AppStore Method: The Application Store of this smartphone is Google Play");    
  38.          }    
  39.       }    
  40.    
  41.       class Program    
  42.       {    
  43.           static void Main(string[] args) { }    
  44.       }    
  45. }   

This code works fine since various concrete classes implement the interface and provide definitions to its members in their own way. Now if the Apple class wants to implement TouchID features, it can easily be done by defining another interface IFeatures. The Apple class can simply inherit the interface and implement the TouchID functionality to its class. This is the case where an interface is useful instead of an abstract class. 

  1. using System;   
  2.    
  3. namespace InterfaceDemo    
  4. {    
  5.      interface ISmartPhone     
  6.      {    
  7.          void OS();    
  8.          void AppStore();    
  9.      }    
  10.    
  11.      //New Interface meant only for Apple Class    
  12.      interface IFeatures    
  13.      {    
  14.           void TouchID();   
  15.      }   
  16.    
  17.    
  18.      class Apple: ISmartPhone, IFeatures    
  19.      {    
  20.          //OS Method Implementation    
  21.          public void OS()    
  22.          {    
  23.             Console.WriteLine("OS Method: The OS of this smartphone is iOS8");    
  24.          }    
  25.    
  26.          //AppStore Method Implementation    
  27.          public void AppStore()    
  28.          {    
  29.             Console.WriteLine("AppStore Method: The Application Store of this smartphone is iTunes");    
  30.          }   
  31.    
  32.    
  33.          //TouchID Method Implementation    
  34.          public void TouchID()    
  35.          {    
  36.             Console.WriteLine("TouchID Method: This method provides Touch/Gesture control features.");     
  37.          }   
  38.      }    
  39.    
  40.      class Samsung : ISmartPhone    
  41.      {    
  42.          //OS Method Implementation    
  43.          public void OS()    
  44.          {    
  45.             Console.WriteLine("OS Method: The OS of this smartphone is Android");    
  46.          }    
  47.    
  48.          //AppStore Method Implementation    
  49.          public void AppStore()    
  50.          {    
  51.             Console.WriteLine("AppStore Method: The Application Store of this smartphone is Google Play");    
  52.          }    
  53.      }    
  54.    
  55.      class Program    
  56.      {    
  57.          static void Main(string[] args) { }    
  58.      }    
  59. }   

So, this way we can get multiple inheritance in C#. Let's create the objects of the concrete classes Apple and Samsung and build the project.

  1. using System;   
  2.    
  3. namespace InterfaceDemo    
  4. {    
  5.      interface ISmartPhone     
  6.      {    
  7.          void OS();    
  8.          void AppStore();    
  9.      }    
  10.    
  11.      //New Interface meant only for Apple Class    
  12.      interface IFeatures    
  13.      {    
  14.           void TouchID();   
  15.      }   
  16.    
  17.    
  18.      class Apple: ISmartPhone, IFeatures    
  19.      {    
  20.          //OS Method Implementation    
  21.          public void OS()    
  22.          {    
  23.              Console.WriteLine("OS Method: The OS of this smartphone is iOS8");    
  24.          }    
  25.    
  26.          //AppStore Method Implementation    
  27.          public void AppStore()    
  28.          {    
  29.             Console.WriteLine("AppStore Method: The Application Store of this smartphone is iTunes");    
  30.          }   
  31.    
  32.          //TouchID Method Implementation    
  33.          public void TouchID()    
  34.          {   
  35.             Console.WriteLine("TouchID Method: This method provides Touch/Gesture Control features.");    
  36.          }   
  37.      }    
  38.    
  39.      class Samsung : ISmartPhone    
  40.      {    
  41.          //OS Method Implementation    
  42.          public void OS()    
  43.          {    
  44.             Console.WriteLine("OS Method: The OS of this smartphone is Android");    
  45.          }    
  46.    
  47.          //AppStore Method Implementation    
  48.          public void AppStore()    
  49.          {    
  50.             Console.WriteLine("AppStore Method: The Application Store of this smartphone is Google Play");    
  51.          }    
  52.       }    
  53.    
  54.       class Program    
  55.       {    
  56.           static void Main(string[] args)    
  57.          {    
  58.              Console.WriteLine("//////////////////// - Interface Demo - //////////////////// \n");                       
  59.              Console.WriteLine("Apple SmartPhone:");    
  60.              Apple apple = new Apple();    
  61.              apple.OS();    
  62.              apple.AppStore();    
  63.              apple.TouchID();    
  64.                 
  65.             Console.WriteLine("\n\n");    
  66.             Console.WriteLine("Samsung SmartPhone:");    
  67.             Samsung samsung = new Samsung();    
  68.             samsung.OS();    
  69.             samsung.AppStore();    
  70.             Console.ReadKey(); }   
  71.       }    
  72. }   

If we run the code now, it works perfectly. 

compile demo

This is the simplest example of using interfaces. However, this is just a real-world analogy and the approach can be debatable. My intent in this demo is to let beginners understand how to work with interfaces. The following are the key points to be remembered when working with interfaces.  

Key Points of C# Interface

  1. Interface Reference Variable

    An interface has no implementation and cannot be instantiated. However, it can be referenced to the class object that implements it. It may be noted that the object can only access the inherited members of the interface. Consider the following code:

    1. using System;    
    2.    
    3. namespace InterfaceDemo    
    4. {    
    5.     interface IDriveable    
    6.     {    
    7.         void Drive();    
    8.     }    
    9.        
    10.     class Car : IDriveable    
    11.     {    
    12.       public void Drive()    
    13.       {    
    14.           Console.WriteLine("Car Class: I can drive a Car.");    
    15.       }    
    16.     }    
    17.    
    18.     class Truck : IDriveable    
    19.     {    
    20.         public void Drive()    
    21.         {    
    22.            Console.WriteLine("Truck Class: I can drive a Truck.");    
    23.         }    
    24.     }    
    25.    
    26.     class Program    
    27.     {    
    28.        static void Main(string[] args)    
    29.        {    
    30.          Console.WriteLine("//////////////////// - Interface Demo - //////////////////// \n");                   
    31.          IDriveable DriveCar = new Car();    
    32.          IDriveable DriveTruck = new Truck();    
    33.    
    34.          DriveCar.Drive();         //Calls Car's Drive() method   
    35.          DriveTruck.Drive();       //Calls Truck's Drive() method   
    36.          Console.ReadKey();    
    37.         }    
    38.       }    
    39. }   
    The code shows the declaration of objects with the same interface Reference but with various functionalities. 

    interface demo

  2. Explicit Interface Implementation

    When working with interfaces, there occurs a situation when a class implements two interfaces and both the interfaces contain a member with the same signature. When the class provides a definition to interface members, it gets confused about which member gets the definition since both have the same name. In that case, we'll an Explicit Interface Implementation.

    Suppose we have two interfaces ICreditCard and IDebitCard and both of these interfaces have the same method signature called CardNumber and a class Customer implements both of these interfaces.

    1. using System;    
    2.    
    3. namespace InterfaceDemo    
    4. {    
    5.       //First Interface IDebitCard   
    6.       interface IDebitCard    
    7.       {    
    8.          void CardNumber();    
    9.       }    
    10.    
    11.       //Second Interface ICreditCard    
    12.       interface ICreditCard    
    13.       {    
    14.          void CardNumber();    
    15.       }    
    16.    
    17.       //Customer Class implementing both the Interfaces    
    18.       class Customer: IDebitCard, ICreditCard    
    19.      {    
    20.      }    
    21.    
    22.      class Program    
    23.      {    
    24.        static void Main(string[] args) { }    
    25.      }    
    26. }   
    There are two ways to provide method definitions to interface members in a derived class. If you right-click on the interface name, Visual Studio gives you two options to implement them. 

    implement interface

    If we implement the interface normally and provide a definition to the CardNumber method, it will cause both interfaces to use CardNumber as their implementation. We cannot provide different functionality to the interface members.
    1. using System;    
    2.    
    3. namespace InterfaceDemo    
    4. {    
    5.       //First Interface IDebitCard    
    6.       interface IDebitCard    
    7.       {    
    8.         void CardNumber();    
    9.       }    
    10.    
    11.       //Second Interface ICreditCard    
    12.       interface ICreditCard    
    13.       {    
    14.            void CardNumber();    
    15.       }    
    16.    
    17.       //Customer Class implements both the interfaces    
    18.       class Customer: IDebitCard, ICreditCard    
    19.       {    
    20.           public void CardNumber()    
    21.           {    
    22.               Console.WriteLine("Card Number: My Card Number is 12345678901234567890");    
    23.           }    
    24.       }    
    25.    
    26.       class Program   
    27.       {    
    28.          static void Main(string[] args)    
    29.         { }    
    30. }   

    If we compile the program now, the output creates more confusion since we are unable to decide which interface method was implemented since both of the interfaces share CardNumber as their method.

    In this case, we need to tell the compiler which method is specific to which interface using Explicit Implementation. It can be done by prefixing the interface name with the method definitions in the derived class. It may be noted that explicit interface definitions are automatically public and hence no access modifier is allowed with the method definitions. We can still have the shared method definition in it.

    1. using System;    
    2.    
    3. namespace InterfaceDemo    
    4. {    
    5.      //First Interface IDebitCard    
    6.      interface IDebitCard    
    7.      {     
    8.        void CardNumber();    
    9.      }    
    10.    
    11.      //Second Interface ICreditCard    
    12.      interface ICreditCard    
    13.      {    
    14.        void CardNumber();    
    15.      }    
    16.    
    17.      //Customer Class implements both the interfaces    
    18.      class Customer: IDebitCard, ICreditCard    
    19.      {   
    20.     
    21.        void IDebitCard.CardNumber()    
    22.        {    
    23.          Console.WriteLine("Debit Card Number: My Card Number is 12345XXXXX");    
    24.        }    
    25.           
    26.        void ICreditCard.CardNumber()    
    27.        {    
    28.           Console.WriteLine("Credit Card Number: My Card Number is 98999XXXXX");    
    29.        }    
    30.           
    31.        public void CardNumber()    
    32.        {    
    33.           Console.WriteLine("Customer ID Number: My ID Number is 54545XXXXX");    
    34.        }    
    35.      }    
    36.    
    37.      class Program    
    38.      {    
    39.        static void Main(string[] args)    
    40.        {    
    41.           Console.WriteLine("////////////////////- Implicit and Expliction Implementation -//////////////////// \n\n");    
    42.           Customer customer = new Customer();    
    43.           IDebitCard DebitCard = new Customer();    
    44.           ICreditCard CreditCard = new Customer();    
    45.    
    46.           customer.CardNumber();    
    47.           DebitCard.CardNumber();    
    48.           CreditCard.CardNumber();    
    49.    
    50.           Console.ReadKey();    
    51.        }    
    52.      }    
    53. }   
    If we run the program now, we are able to differentiate members using an Explicit Interface.

    implicit and expliction implementation

  3. If you have some kind of default functionality to share across classes in the hierarchy, you can use an abstract class. But if you don't have any default implementation and just need to define contracts for derived classes to follow; interface is the most preferred choice.

  4. It is a standard rule when using an interface, be sure you have done it right the first time. Once the interface is implemented by derived classes, it is difficult to update or modify the interface since everyone else's code breaks.

1. A class can implement any number of interfaces but a subclass can at most use only one abstract class.

 
2. An abstract class can have non-abstract Methods(concrete methods) while in case of Interface all the methods has to be abstract.
 
3. An abstract class can declare or use any variables while an interface is not allowed to do so.
 
So following code will not compile
  1. interface TestInterface  
  2. {  
  3.     int x = 4;  // Filed Declaration in Interface  
  4.     void getMethod();  
  5.     string getName();  
  6. }  
  7.   
  8. abstract class TestAbstractClass  
  9. {  
  10.     int i = 4;  
  11.     int k = 3;  
  12.     public abstract void getClassName();  
  13. }  
It will generate a compile time error as
 
Error 1 Interfaces cannot contain fields.
 
So we need to omit Field Declaration in order to compile the code properly.
  1. interface TestInterface  
  2. {  
  3.     void getMethod();  
  4.     string getName();  
  5. }   
  6.   
  7. abstract class TestAbstractClass  
  8. {  
  9.     int i = 4;  
  10.     int k = 3;  
  11.     public abstract void getClassName();  
  12. }  
Above code compiles properly as no field declaration is there in Interface.
 
4. An abstract class can have constructor declaration while an interface can not do so.
 
So following code will not compile
  1. interface TestInterface  
  2. {  
  3.     // Constructor Declaration  
  4.     public TestInterface()  
  5.     {  
  6.     }  
  7.     void getMethod();  
  8.     string getName();  
  9. }  
  10.   
  11. abstract class TestAbstractClass  
  12. {  
  13.     public TestAbstractClass()  
  14.     {  
  15.     }  
  16.     int i = 4;  
  17.     int k = 3;  
  18.     public abstract void getClassName();  
  19. }  
Above code will generate a compile time error as
 
Error 1 Interfaces cannot contain constructors
 
So we need to omit constructor declaration from interface in order to compile our code.
 
Following code compile s perfectly
  1. interface TestInterface  
  2. {  
  3.     void getMethod();  
  4.     string getName();  
  5. }  
  6.   
  7. abstract class TestAbstractClass  
  8. {  
  9.     public TestAbstractClass()  
  10.     {  
  11.     }  
  12.     int i = 4;  
  13.     int k = 3;  
  14.     public abstract void getClassName();  
  15. }  
5. An abstract Class is allowed to have all access modifiers for all of its member declaration while in interface we can not declare any access modifier(including public) as all the members of interface are implicitly public.
 
Note here I am talking about the access specifiers of the member of interface and not about the interface.
 
Following code will explain it better
 
It is perfectly legal to give provide access specifier as Public (Remember only public is allowed)
  1. public interface TestInterface  
  2. {  
  3.     void getMethod();  
  4.     string getName();  
  5. }  
Above code compiles perfectly.
 
It is not allowed to give any access specifier to the members of the Interface.
  1. interface TestInterface  
  2. {  
  3.     public void getMethod();  
  4.     public string getName();  
  5. }  
Above code will generate a compile time error as
 
Error 1 The modifier 'public' is not valid for this item.
 
But the best way of declaring Interface will be to avoid access specifier on interface as well as members of interface.
  1. interface Test  
  2. {  
  3.     void getMethod();  
  4.     string getName();  
  5. }

    Following are the important differences between Abstract Class and Interface.

    Sr. No.KeyAbstract ClassInterface
    1DefinitionIn terms of standard definition an Abstract class is, conceptually, a class that cannot be instantiated and is usually implemented as a class that has one or more pure virtual (abstract) functions.On other hand an Interface is a description of what member functions must a class, which inherits this interface, implement. In other words, an interface describes behaviour of the class.
    2ImplementationAs like of other general class design in C# Abstract class also have its own implementation along with its declaration.On other hand an Interface can only have a signature, not the implementation. While its implementation is being provided by the class which implements it.
    3InheritanceAs per specification in C# a class can extends only one other class hence multiple inheritance is not achieved by abstract class.On other hand in case of Interface a class can implements multiple interfaces and hence multiple inheritance is achieved by interface.
    4ConstructorLike other classes in C# for instantiation abstract class also have constructor which provide an instance of abstract class to access its non-static methods.On other hand Interface do not have constructor so we can't instantiate an interface directly although its method could get accessed by creating instance of class which implementing it.
    5ModifiersAs abstract class is most like of other ordinary class in C# so it can contain different types of access modifiers like public, private, protected etc.On other hand as Interface needs to be get implemented in order to provide its methods implementation by other class so can only contains public access modifier.
    6PerformanceAs abstract class have its method as well as their implementations also for its abstract methods implementation it have reference for its implementing class so performance is comparatively faster as compare to that of Interface.On other hand the performance of interface is slow because it requires time to search actual method in the corresponding class.

    Difference between Abstract Class and Interface

    ABSTRACT CLASSINTERFACE
    It contains both declaration and definition part.It contains only a declaration part.
    Multiple inheritance is not achieved by abstract class.Multiple inheritance is achieved by interface.
    It contain constructor.It does not contain constructor.
    It can contain static members.It does not contain static members.
    It can contain different types of access modifiers like public, private, protected etc.It only contains public access modifier because everything in the interface is public.
    The performance of an abstract class is fast.The performance of interface is slow because it requires time to search actual method in the corresponding class.
    It is used to implement the core identity of class.It is used to implement peripheral abilities of class.
    A class can only use one abstract class.A class can use multiple interface.
    If many implementations are of the same kind and use common behavior, then it is superior to use abstract class.If many implementations only share methods, then it is superior to use Interface.
    Abstract class can contain methods, fields, constants, etc.Interface can only contain methods .
    It can be fully, partially or not implemented.It should be fully implemented.

1 comment:

  1. Thank you for your post. This is excellent information. It is amazing and wonderful to visit your site. For more info:- Xamarin App Development

    ReplyDelete

All About .NET MAUI

  What’s .NET MAUI? .NET MAUI (.NET Multi-platform App UI) is a framework for building modern, multi-platform, natively compiled iOS, Androi...

Ads2