Learn Tiny Bit Of C# In 7 Days - Day 3

Before reading this article, I highly recommend reading my previous parts:

Learn tiny bit of C Sharp

  1. Interface
  2. Abstract class
  3. Abstract classes vs Interface

In Day 3 we have kept few topics but these topics are important that need in depth knowledge in order to understand them, I hope that you will enjoy Day 3 of learning tiny bit of C#.

Interface

Interface is like a class that cannot contain the definition i.e. it contains empty events, methods and properties. We create Interface using interface keyword. Just like classes, interface contains properties, methods, members, delegates or event but only declaration and no implementation.
In one term we call Interface as a contract because they force the class to follow the contract between Class and Interface.

Syntax

  1. interface ICustomer //Write Interface and name of Interface  
  2. {  
  3.    void Bonus();//definition of method  
  4.   
  5. }  
  • Interface cannot contain Fields (variables)

    E.g.
    1. public interface ICustomer  
    2. {  
    3.    int CustomerName;  
    4. }  
    If we try to declare a field inside an Interface we face a compile time error saying Interface cannot contain fields. We can declare a public.

    contain fields

  • Interface member cannot have a definition.

    This means that a function of Interface cannot have its definition of its own.

    E.g.
    1. public interface ICustomer  
    2. {  
    3.     void Print()  
    4.     {  
    5.         Console.WriteLine("Hello");  
    6.     }  
    7. }  
    function of Interface

How to implement Interface

As we inherit a class in C# using (:) same we have to do when we want to implement an Interface.

  • We need to Implement the Interface members,

    If we just implement the Interface and does not implement the properties or function it will threw a compile time error as shown below:
    1. public interface ICustomer  
    2. {  
    3.     int _Name  
    4.     {  
    5.         get;  
    6.         set;  
    7.     }  
    8.     void Print();  
    9. }  
    10. public class Customer: ICustomer  
    11. {}  
    See error

  • When we implement the Interface the members should be Public,

    E.g.
    1. public interface ICustomer  
    2. {  
    3.     int _Name  
    4.     {  
    5.         get;  
    6.         set;  
    7.     }  
    8.     void Print();  
    9. }  
    10. public class Customer: ICustomer  
    11. {  
    12.     public int _Name  
    13.     {  
    14.         get  
    15.         {  
    16.             throw new NotImplementedException();  
    17.         }  
    18.         set  
    19.         {  
    20.             throw new NotImplementedException();  
    21.         }  
    22.     }  
    23.     void Print()  
    24.     {  
    25.         throw new NotImplementedException();  
    26.     }  
    27. } * Implement the Interface members  
    28. public interface ICustomer  
    29. {  
    30.     int _Name  
    31.     {  
    32.         get;  
    33.         set;  
    34.     }  
    35.     void Print();  
    36. }  
    37. public class Customer: ICustomer  
    38. {  
    39.     public int _Name  
    40.     {  
    41.         get  
    42.         {  
    43.             throw new NotImplementedException();  
    44.         }  
    45.         set  
    46.         {  
    47.             throw new NotImplementedException();  
    48.         }  
    49.     }  
    50.     public void Print()  
    51.     {  
    52.         throw new NotImplementedException();  
    53.     }  
    54. }  
    55. namespace Interface  
    56. {  
    57.     interface ICustomer  
    58.     {  
    59.         void Bonus();  
    60.     }  
    61.     class Customer: ICustomer //implementing Interface  
    62.     {  
    63.         public void Bonus() //implementing the function of ICustomer Interface  
    64.         {  
    65.             Console.WriteLine("Bonus of this year");  
    66.             Console.ReadLine();  
    67.         }  
    68.     }  
    69. }  

Interface member are public by default, and they allow explicit modifiers if a class inherits from an interface it must provide implementation for all interface members. Otherwise, we get a compiler error, as shown below.

interface members

Now once we implement the interface the above mentioned error gets resolved.

implement the interface

We can see the command prompt window with the output:

What if a Class implementing an Interface inherits another Interface

  1. using System;  
  2. namespace Interface  
  3. {  
  4.     interface ICustomer  
  5.     {  
  6.         void Print();  
  7.     }  
  8.     interface Icustomer2: ICustomer  
  9.     {  
  10.         void Print2();  
  11.     }  
  12.     public class Customer: Icustomer2  
  13.     {  
  14.         public void Print2()  
  15.         {  
  16.             Console.WriteLine("ICustomer2 Method");  
  17.         }  
  18.     }  
  19.     class Program  
  20.     {  
  21.         static void Main(string[] args)  
  22.         {  
  23.             Customer objCustomer = new Customer();  
  24.             objCustomer.Print2();  
  25.         }  
  26.     }  
  27. }  
Now once I try to build the same I face the following error:

build

When a class implements an Interface which inherits other Interface then the class has to provide the implementation for both the Interface methods.
  1. public class Customer: Icustomer2  
  2. {  
  3.     public void Print2()  
  4.     {  
  5.         Console.WriteLine("ICustomer2 Method");  
  6.     }  
  7.     public void Print()  
  8.     {  
  9.         Console.WriteLine("ICustomer1 Method");  
  10.     }  
  11. }  
Now once I implement the other Interface method and try to build the application it gets successfully build.

gets successfully build

We cannot create an instance of Interface, but an Interface reference variable can be pointed towards a class object which is implementing the Interface.

Now the question comes why we should use Interface: 
  1. ENFORCE the Standardization/ consistency(Contract)
  2. Decoupling

ENFORCE the Standardization/ consistency (Contract)

In law, a contract (or informally known as an agreement in some jurisdictions) is an agreement having a lawful object entered into voluntarily by two or more parties, each of whom intends to create one or more legal obligations between them. Source: Wikipedia.

Basically by the words contract we mean that class will implement all methods of Interface. Class that implements the Interface here signs the Contract that I will implement all the methods, etc. of the Interface. We will be showing the example for the same in the following example.

Decoupling

Decoupling as the word specifies dissociate (something) from something else, so here in programming world decoupling stand where we separate the dependency between our business layer concrete classes, UI layer and DAL Layer as shown below. As we have seen we cannot create an object of the Interface, but an Interface reference variable can point towards a derived class object.

So let’s get started we will create a Registration Page where we will be inserting the User Details into the database without directly calling BAL or DAL from the concrete classes rather we will call these classes via an Interface. This topic will be little bit difficult to understand. Please focus and try to go with a practical  implementation.

So switch to Visual Studio:

  • I have created a web application named TestInterface which is basically a Web Form based application.
  • We create a UI as shown below:

    UI

So when we create an Enterprise application we should make them in 3 layer architecture which means UI, BAL (Business Layer or Concrete classes) and DAL Data Access Layer.

So we have created our UI which generally talk to the concrete classes and then the concrete classes talk with DAL class to insert or update or delete information and vice versa. In this scenario we make a strong coupling between our Layers that means our Layers are not decoupled from each other in order to make them decoupled we make use of an Interface.

  • Now we will create our Business Class called User.cs which will contain properties related to the user like FirstName, LastName, Address and MobileNo)

  • We create an Interface called ICRUD (Create, Read, Update and Delete) where we will define our Methods that will be enforced to be implemented by the User Class.

  • We create our IRegister Interface which will implement ICRUD and contains properties as in the following:
    1. public interface IRegister  
    2. {  
    3.   
    4.    string FirstName { getset; }  
    5.    string LastName { getset; }  
    6.    string Address { getset; }  
    7.    string MobileNo { getset; }  
    8.   
    9. }   
  • Now we will also create an Interface responsible for communicating between our BAL and DAL layer and will also decide which DB to be used. (SQL Server or oracle).
    1. public interface IDb  
    2. {  
    3.     /// <summary>  
    4.     /// Insert to method will take 4 parameters to save the information to the db  
    5.     /// and return the generated ID for the User and same will be displayed to the User  
    6.     /// </summary>  
    7.     /// <param name="_FirstName">Coming from BAL RegisterUser _FirstName property</param>  
    8.     /// <param name="_LastName">Coming from BAL RegisterUser _LastName property</param>  
    9.     /// <param name="_Address">Coming from BAL RegisterUser _Address property</param>  
    10.     /// <param name="_MobileNo">Coming from BAL RegisterUser _MobileNo property</param>  
    11.     /// <returns></returns>  
    12.     int Insert(string _FirstName, string _LastName, string _Address, string _MobileNo);  
    13. }  

Here I have only created one method while we can create all the operations that we need to perform as per our business requirements.

Now once we have created our Interface let us implement the Interface in our BAL class.

  1. using System;  
  2. using System.Collections.Generic;  
  3. using System.Linq;  
  4. using System.Text;  
  5. using System.Threading.Tasks;  
  6. using Interface;  
  7. namespace BAL  
  8. {  
  9.     public class User: IRegister  
  10.     {  
  11.         public string FirstName  
  12.         {  
  13.             get  
  14.             {  
  15.                 throw new NotImplementedException();  
  16.             }  
  17.             set  
  18.             {  
  19.                 throw new NotImplementedException();  
  20.             }  
  21.         }  
  22.         public string LastName  
  23.         {  
  24.             get  
  25.             {  
  26.                 throw new NotImplementedException();  
  27.             }  
  28.             set  
  29.             {  
  30.                 throw new NotImplementedException();  
  31.             }  
  32.         }  
  33.         public string Address  
  34.         {  
  35.             get  
  36.             {  
  37.                 throw new NotImplementedException();  
  38.             }  
  39.             set  
  40.             {  
  41.                 throw new NotImplementedException();  
  42.             }  
  43.         }  
  44.         public string MobileNo  
  45.         {  
  46.             get  
  47.             {  
  48.                 throw new NotImplementedException();  
  49.             }  
  50.             set  
  51.             {  
  52.                 throw new NotImplementedException();  
  53.             }  
  54.         }  
  55.         public int InsertUser()  
  56.         {  
  57.             throw new NotImplementedException();  
  58.         }  
  59.     }  
  60. }  
Note: Our IRegister Interface implements ICRUD interface so now class has to implement both the functionality of IRegister as well as ICRUD Interface as shown above.

We will write our implementation functionality for UserClass.
  1. using System;  
  2. using System.Collections.Generic;  
  3. using System.Linq;  
  4. using System.Text;  
  5. using System.Threading.Tasks;  
  6. using Interface;  
  7. namespace BAL  
  8. {  
  9.     public class User: IRegister  
  10.     {  
  11.         private int _UserId;  
  12.         private string _FirstName;  
  13.         private string _Address;  
  14.         private string _LastName;  
  15.         private string _MobileNo;  
  16.         public string FirstName  
  17.         {  
  18.             get  
  19.             {  
  20.                 return _FirstName;  
  21.             }  
  22.             set  
  23.             {  
  24.                 _FirstName = value;  
  25.             }  
  26.         }  
  27.         public string LastName  
  28.         {  
  29.             get  
  30.             {  
  31.                 return _LastName;  
  32.             }  
  33.             set  
  34.             {  
  35.                 _LastName = value;  
  36.             }  
  37.         }  
  38.         public string Address  
  39.         {  
  40.             get  
  41.             {  
  42.                 return _Address;  
  43.             }  
  44.             set  
  45.             {  
  46.                 _Address = value;  
  47.             }  
  48.         }  
  49.         public string MobileNo  
  50.         {  
  51.             get  
  52.             {  
  53.                 return _MobileNo;  
  54.             }  
  55.             set  
  56.             {  
  57.                 _MobileNo = value;  
  58.             }  
  59.         }  
  60.         public int InsertUser(IDb obj)  
  61.         {  
  62.             _UserId = obj.Insert(_FirstName, _LastName, _Address, _MobileNo);  
  63.             return _UserId;  
  64.         }  
  65.     }  
  66. }  
Note: Here IDb Interface will communicate between BAL and DAL layer and will also decide which DB server will be used: SQL Server or Oracle.

Now we will create DAL layer. Here I am not using stored procedure to insert User Records to the Database but will request you to use stored procedure for the same.
  1. using System;  
  2. using System.Collections.Generic;  
  3. using System.Linq;  
  4. using System.Text;  
  5. using System.Threading.Tasks;  
  6. using System.Data;  
  7. using System.Data.SqlClient;  
  8. using System.Data.OracleClient;  
  9. using Interface;  
  10. using System.Configuration;  
  11. namespace DAL  
  12. {  
  13.     public class SqlServer: IDb  
  14.     {  
  15.         //connection string   
  16.         static private string connectionString;  
  17.         //sql connection   
  18.         static private SqlConnection con;  
  19.         static SqlServer()  
  20.         {  
  21.             connectionString = ConfigurationManager.ConnectionStrings["SqlDB"].ConnectionString;  
  22.             con = new SqlConnection(connectionString);  
  23.         }  
  24.         public int Insert(string firstName, string lastName, string mobileNo, string addreess)  
  25.         {  
  26.             try  
  27.             {  
  28.                 string query = "insert into tblRegistration values ('" + firstName + "','" + lastName + "','" + mobileNo + "','" + addreess + "')";  
  29.                 //creating sql command object and passing query and connection object  
  30.                 SqlCommand cmd = new SqlCommand(query, con);  
  31.                 con.Open();  
  32.                 cmd.ExecuteScalar();  
  33.                 string query2 = "select IDENT_CURRENT('tblRegistration')";  
  34.                 SqlCommand cmd2 = new SqlCommand(query2, con);  
  35.                 decimal value = (decimal) cmd2.ExecuteScalar();  
  36.                 return Convert.ToInt32(value);  
  37.             }  
  38.             catch (Exception ex)  
  39.             {  
  40.                 throw new Exception(ex.Message.ToString());  
  41.             }  
  42.             finally  
  43.             {  
  44.                 con.Close();  
  45.             }  
  46.         }  
  47.     }  
  48.     public class Oracle: IDb  
  49.     {  
  50.         static private string connectionString;  
  51.         static private OracleConnection con;  
  52.         static Oracle()  
  53.         {  
  54.             connectionString = ConfigurationManager.ConnectionStrings["OracleDB"].ConnectionString;  
  55.             con = new OracleConnection(connectionString);  
  56.         }  
  57.         public int Insert(string firstName, string lastName, string mobileNo, string addreess)  
  58.         {  
  59.             try  
  60.             {  
  61.                 string query = "insert into tblRegistration values ('" + firstName + "','" + lastName + "','" + mobileNo + "','" + addreess + "')";  
  62.                 OracleCommand cmd = new OracleCommand(query, con);  
  63.                 con.Open();  
  64.                 cmd.ExecuteScalar();  
  65.                 string query2 = "select INCR_USERID.currval from dual";  
  66.                 OracleCommand cmd2 = new OracleCommand(query2, con);  
  67.                 decimal value = (decimal) cmd2.ExecuteScalar();  
  68.                 return Convert.ToInt32(value);  
  69.             }  
  70.             catch (Exception ex)  
  71.             {  
  72.                 throw new Exception(ex.Message.ToString());  
  73.             }  
  74.             finally  
  75.             {  
  76.                 con.Close();  
  77.             }  
  78.         }  
  79.     }  
  80. }  
Now here we have created our DAL class which implements IDb Interface which works as a communication between BAL and DAL layer. It has only one method as shown above:

Now in the UI rather than creating an object of the Business class we give this job to a Factory Class which will be responsible for creating objects of the desired class which is needed. Factory class basically is a type of creational pattern. As we know that Interface cannot create object of its own but it can reference to the object of the implemented class. Here we have only one class but in real time project we will have lots of classes this may vary for the same and can be improvised with other design patterns.
  1. using Interface;  
  2. using BAL;  
  3. namespace Factory  
  4. {  
  5.     public class Factory  
  6.     {  
  7.         public static IRegister getRegisterobject()  
  8.         {  
  9.             return new User();  
  10.         }  
  11.     }  
  12. }  
Now once we have implemented the Factory class let’s get the Information from UI and try to insert the same.
  1. using System;  
  2. using Interface;  
  3. using System.Configuration;  
  4. using DAL;  
  5. namespace TestInterface  
  6. {  
  7.     public partial class Register: System.Web.UI.Page  
  8.     {  
  9.         IDb objIDB = null;  
  10.         string DBname = ConfigurationManager.AppSettings["DB"].ToString()  
  11.             .ToLower();  
  12.         protected void Page_Load(object sender, EventArgs e)  
  13.         {  
  14.             if (DBname == "oracle")  
  15.             {  
  16.                 objIDB = new Oracle();  
  17.             }  
  18.             else  
  19.             {  
  20.                 objIDB = new SqlServer();  
  21.             }  
  22.         }  
  23.         protected void Button1_Click(object sender, EventArgs e)  
  24.         {  
  25.             IRegister objRegister = Factory.Factory.getRegisterobject();  
  26.             setObjectFromUi(objRegister);  
  27.             int Id = objRegister.InsertUser(objIDB);  
  28.             Response.Write("User Registered successfully with UserId " + Id);  
  29.         }  
  30.         private void setObjectFromUi(IRegister userInformation)  
  31.         {  
  32.             userInformation.FirstName = txtFirstName.Text;  
  33.             userInformation.LastName = txtLastName.Text;  
  34.             userInformation.MobileNo = txtMobile.Text;  
  35.             userInformation.Address = txtAddress.Text;  
  36.         }  
  37.     }  
  38. }  
Here at the start of the application we check from the web.config file which DB to be used based upon the entry IDb Interface will reference towards the SQL Server or Oracle Server.
  1. IDb objIDB = null;  
  2. string DBname = ConfigurationManager.AppSettings["DB"].ToString()  
  3.     .ToLower();  
  4. // retrieving information about Db from the app settings  
  5. protected void Page_Load(object sender, EventArgs e)  
  6. {  
  7.     if (DBname == "oracle")  
  8.     {  
  9.         //if string contains oracle than reference towards Oracle else towards Sqlserver  
  10.         objIDB = new Oracle();  
  11.     }  
  12.     else  
  13.     {  
  14.         objIDB = new SqlServer();  
  15.     }  
  16. }  
Now once the User enters the information IRegister will call Factory class to create object of User and IRegister will refer towards User Class.
  1. IRegister objRegister = Factory.Factory.getRegisterobject();  
  2. Than setObjectFromUi(objRegister);  
  3. //All user information will be set to Properties.  
  4. private void setObjectFromUi(IRegister userInformation)  
  5. {  
  6.     userInformation.FirstName = txtFirstName.Text;  
  7.     userInformation.LastName = txtLastName.Text;  
  8.     userInformation.MobileNo = txtMobile.Text;  
  9.     userInformation.Address = txtAddress.Text;  
  10. }  
  11. int Id = objRegister.InsertUser(objIDB);  
IRegister reference object will call InsertUser method and pass IDb reference object and at the User class same will be received and then Idb will communicate with DAL layer.
  1. public int InsertUser(IDb obj)  
  2. {  
  3.     _UserId = obj.Insert(_FirstName, _LastName, _Address, _MobileNo);  
  4.     return _UserId;  
  5. }  
We can see that there is no object creation of Concrete class and Db classes rather Interface has been used to reference to those classes making our project decoupled from each other. Let’s run our application and see how it works.

Phase 1

Code

Phase 2: IDb referencing towards SqlServer Class,

IDb referencing towards SqlServer Class

Phase 3: Loading connection string,

Loading connection string

Phase 4: Register Page Appear,

Register Page Appear

Phase 5: As soon as User Enters the information.

Factory class getRegisterObject function will be called and Iregister reference variable will point towards User class,

getRegisterObject

Phase 6: Creation of User Object,

Creation of User Object

Phase 7: Setting User Information into properties of Class.

We can clearly see that all work is done by Interface we are not creating any object of class Interface communicating with all.

Interface

Phase 8: Class method InsertUser will be called and Reference variable of IDb will be passed which point towards the DB which we want to use.

method InsertUser

Phase 9: Here we can see Idb ibj contains reference variable towards SQL Server, now all the fields value will be passed to the db Insert function. As shown below we have used _UsedId field to receive the generated UserId of the User.

generated UserId of the User

Phase 10: Now SQl server class method will be called by IDb interface and the queries are executed and the generated UserId will be returned back to User UI screen.

SQl server class method

Phase 11: Showing UserId generated and same will be returned to User UI.

UserId

Submit

So here we learnt how Interface helps us to follow the standardization of Vocabulary and helps in Decoupling. I hope all phases would be helpful so that you can learn them phase by phase. I have attached the project and will request you to execute the same.

Explicit Interface

Think of a scenario where we have two Interfaces with same method name then how we will be able to tell the method which we implemented is of which Interface.
  1. public interface IPrintSony  
  2. {  
  3.     void Print();  
  4. }  
  5. public interface IPrintHP  
  6. {  
  7.     void Print();  
  8. }  
  9. public class Customer: IPrintHP, IPrintSony  
  10. {  
  11.     public void Print()  
  12.     {  
  13.         Console.WriteLine("I am an Interface function");  
  14.         Console.ReadLine();  
  15.     }  
  16.     public static void Main()  
  17.     {  
  18.         Customer objCustomer = new Customer();  
  19.         objCustomer.Print();  
  20.     }  
  21. }  
Here as you can see there are two Interface IPrintSony and IPrintHP. Customer class is implementing both the Interface and implementing the methods, we run the program and found that it runs. So how do we figure out which interface method was called so in order to achieve that we make use of Explicit Interfaces as shown below.
  1. namespace ConsoleApplication1  
  2. {  
  3.     public interface IPrintSony  
  4.     {  
  5.         void Print();  
  6.     }  
  7.     public interface IPrintHP  
  8.     {  
  9.         void Print();  
  10.     }  
  11.     public class Customer: IPrintHP, IPrintSony  
  12.     {  
  13.         void IPrintSony.Print()  
  14.         {  
  15.             Console.WriteLine("I am an IPrintSony Interface function");  
  16.             Console.ReadLine();  
  17.         }  
  18.         void IPrintHP.Print()  
  19.         {  
  20.             Console.WriteLine("I am an IPrintHP Interface function");  
  21.             Console.ReadLine();  
  22.         }  
  23.         public static void Main()  
  24.         {  
  25.             Customer objCustomer = new Customer();  
  26.             ((IPrintHP) objCustomer)  
  27.             .Print();  
  28.             ((IPrintSony) objCustomer)  
  29.             .Print();  
  30.         }  
  31.     }  
  32. }  
run

Hereby I conclude that once the class explicitly implements the Interface the Interface member can no longer be accessed through class reference variable, but only via Interface reference variable as shown above.

Abstract Class

An Abstract class is a half defined Base class in C# and we cannot create the object of the Abstract class. You can create your own Abstract class by using the modifier called Abstract. An abstract class means we cannot create object of the same but we can inherit the Abstract class in our child classes. 
  • Abstract Class only comes in Inheritance hierarchy i.e. Is A relationship.
  • Abstract is used in order to remove duplication in Inheritance model using Generalization and Specialization relationship.

Abstract keyword is used to create Abstract class e.g.:

  1. abstract class Customer  
  2. {  
  3.   
  4. }  
An Abstract Class can contain abstract methods i.e. that only contain definition they don’t have implementation of their own, abstract methods implementation is done in Child or Derived classes otherwise it will throw error note (all the child has to implement all abstract methods). Abstract method can also contain non abstract methods.
  1. namespace AbstractClass  
  2. {  
  3.     abstract class Customer  
  4.     {  
  5.         public abstract void print();  
  6.     }  
  7. }  
But if I try to give implementation to the abstract class we will face an Error. We cannot define an Abstract class as static or sealed (it will not be inherited). We cannot define the access modifier for Abstract class it is by default Public.

sealed
i.e. Abstract methods cannot contain implementation.

As discussed above we cannot create object of the Abstract class. Let us try the same, so as soon as we create an instance of the Abstract class. Abstract class can be used as a Base class for other classes.

Abstract class

When we declare a method as Abstract and we inherit the Abstract class we have to implement the Abstract method otherwise it will throw an exception.
  1. namespace Abstract  
  2. {  
  3.     abstract class PERSON  
  4.     {  
  5.         public abstract void Print();  
  6.     }  
  7.     class Program: PERSON  
  8.     {  
  9.         static void Main(string[] args)  
  10.         {}  
  11.     }  
  12. }  
Abstract method

But if we don’t want to provide the implementation for the Abstract method we can put Abstract keyword in class Program, it will not throw an error and will mark it as an Abstract class i.e. that means this Abstract class has some Abstract members.

In order to implement abstract methods in Derived class we have to use override in the abstract methods of Abstract class. Small example is shown below:

override

Here Employee is a generalized entity which has generalized properties which later inherited and override by the Child entity to define specialized relationship.

Like Consultant Employee, FullTime Employee.
  1. using System;  
  2. namespace AbstractClass  
  3. {  
  4.     abstract class Customer  
  5.     {  
  6.         public int ID  
  7.         {  
  8.             get;  
  9.             set;  
  10.         }  
  11.         public String UserName  
  12.         {  
  13.             get;  
  14.             set;  
  15.         }  
  16.         public abstract void Details();  
  17.     }  
  18.     class Consultant: Customer  
  19.     {  
  20.         public int HourlySalary  
  21.         {  
  22.             get;  
  23.             set;  
  24.         }  
  25.         public override void Details()  
  26.         {  
  27.             Console.WriteLine("The Consultant name {0} , id {1} and Hourly salary is {2}"this.ID, this.UserName, this.HourlySalary);  
  28.         }  
  29.     }  
  30.     class Fulltime: Customer  
  31.     {  
  32.         public int YearlySalary  
  33.         {  
  34.             get;  
  35.             set;  
  36.         }  
  37.         public override void Details()  
  38.         {  
  39.             Console.WriteLine("The Consultant name {0} , id is {1} and yearly salary is {2}"this.ID, this.UserName, this.YearlySalary);  
  40.         }  
  41.     }  
  42. }  
  43. using System;  
  44. namespace AbstractClass  
  45. {  
  46.     class Program  
  47.     {  
  48.         static void Main(string[] args)  
  49.         {  
  50.             Consultant objcons = new Consultant();  
  51.             objcons.HourlySalary = 4000;  
  52.             objcons.ID = 1;  
  53.             objcons.UserName = "Akansha Bakshi";  
  54.             objcons.Details();  
  55.             Console.ReadLine();  
  56.         }  
  57.     }  
  58. }  
In derived class the abstract method of Abstract class should be of same return type and definition otherwise it will show error. 
  • Non Abstract Methods:

    If we declare method without Abstract keyword it is a Non Abstract method i.e. that means it’s not mandatory to have Abstract members in Abstract class.

  • We cannot create an object of the Abstract class but we can point the Abstract class object to the child class object as in the following example:
    1. public class Program: PERSON  
    2. {  
    3.     public override void Print()  
    4.     {  
    5.         Console.WriteLine("I am child class inheriting abstract class");  
    6.     }  
    7.     static void Main(string[] args)  
    8.     {  
    9.         PERSON objPerson = new Program();  
    10.         objPerson.Print();  
    11.         Console.ReadLine();  
    12.     }  
    13. }  
  • Abstract class cannot be Sealed.

    Error

Why and when should we use Abstract class

Lets’ take an example if we implement the above example doing Inheritance method and creating a concrete class as base and child class Fulltime Employee and Parttime Employee inheriting the Base Class BaseEmployee.

We would be able to create the object of the BaseEmployeeClass, where in real time we only have two employees FullTime and PartTime so it would be wrong if we allow developers the object creation of BaseEmployeeClass. So we want to prevent them to create instance of the BaseEmployee. To solve this problem we use the concept of Abstract class. Once we mark the class as Abstract we cannot create object of the Abstract classes, preventing us from creating object of BaseEmployeeClass.

Hence I can conclude that we should use Abstract class when we want to move common functionality of two or more classes into a single base class and when we don’t want anyone to instantiate the base class.

Abstract classes vs Interface

Abstract Interface
Abstract classes can have implementation for some of its members. Interface cannot have implementation for any of its members.
Abstract class members are by default Private Interface members are by default Public (they cannot have access modifiers)
Abstract class can have fields. Interface cannot contain fields.
• A class can implement multiple interfaces at the same time.
• A class cannot inherit multiple classes at the same time.
 
Abstract classes can be inherited from a class Interface can only be inherited from an Interface.
Abstract classes are used when we want to share common functionality in parent child relationship, which cannot be initiated. Interfaces are used to define the contract enforce the standardization, decoupling
Abstract classes are inherited Interface are implemented
Abstract class member can have Access Modifiers. Interface members are Public because purpose of an interface is to enable other types to access a class or struct. No access modifiers can be applied to interface members.