Click here to Skip to main content
15,888,301 members
Articles / Programming Languages / C#
Tip/Trick

When to Use Abstract Class in C#, Real World Example

Rate me:
Please Sign up or sign in to vote.
3.26/5 (24 votes)
19 Mar 2015CPOL2 min read 98.2K   18   15
When to use Abstract Class in C#, Real Time Example

Introduction

It is a very common discussion when to use Abstract class and what is the benefit of using Abstract class in real time application development. The common properties of Abstract class are it cannot be initiated, functions and implementation can be partially implemented.

Consider an application that calculates salary of full time and contract based employees. There are few common properties of both employees, e.g., both employees have name, address, ID, but different way of calculating salaries. So we can declare one master class named as BaseEmployee and place common properties and Virtual Salary Calculator function with no implementation. Two child classes, FullTimeEmployee and ContractEmployee can inherit from BaseEmployee class and override Salary Calculator virtual function and our problem can be solved, then why Abstract Class should be used?

C#
namespace AbstractClassExample
{
    class Program
    {
        static void Main(string[] args)
        {
            //BaseEmployee Object is created with no compilation error
            BaseEmployee baseEmployee = new BaseEmployee();
            baseEmployee.EmployeeID = "EMP001";
            baseEmployee.EmployeeAddress = "3400 Lee Highway, VA 22031";
            baseEmployee.EmployeeName = "John Doe";

            BaseEmployee fullTimeEmployee = new FullTimeEmployee();
            var fteSalary = fullTimeEmployee.CalculateSalary(40);

            //Base Employee Calculate Salary can be called that shouldn't be accessible
            var baseSalary = baseEmployee.CalculateSalary(34);
        }
    }

    public class BaseEmployee
    {
        public string EmployeeID { get; set; }
        public string EmployeeName { get; set; }
        public string EmployeeAddress { get; set; }

        public virtual double CalculateSalary(int hoursWorked)
        {
            throw new NotImplementedException();
        }
    }

    public class FullTimeEmployee : BaseEmployee
    {
        public override double CalculateSalary(int hoursWorked)
        {
            return hoursWorked * 60.00+4000;
        }
    }

    public class ContractEmployee : BaseEmployee
    {
        public override double CalculateSalary(int hoursWorked)
        {
            return hoursWorked * 65.00;
        }
    }
}

The problem with this inheritance approach is more like logical and business issue, in inheritance we can simply create BaseEmployee object and nothing can stop us which is wrong, usually any normal company does not have any BaseEmployee type employee, so if we want to stop user from accidentally creating a BaseEmployee class object we should declare this class and Salary Calculator as Abstract so that it can only be inherited but not initiated.

C#
namespace AbstractClassExample
{
    class Program
    {
        static void Main(string[] args)
        {
            /*BaseEmployee Object can not be created since this is declared as Abstract
            Following LOCs will return compilation error if uncommented.*/

            //BaseEmployee baseEmployee = new BaseEmployee();
            //baseEmployee.EmployeeID = "EMP001";
            //baseEmployee.EmployeeAddress = "3400 Lee Highway, VA 22031";
            //baseEmployee.EmployeeName = "John Doe";

            //Base Employee Calculate Salary can be called that shouldn't be accessible
            //var baseSalary = baseEmployee.CalculateSalary(34);

            //Full Time and Contract Employees objects are successfully created.
            BaseEmployee fullTimeEmployee = new FullTimeEmployee();
            var fteSalary = fullTimeEmployee.CalculateSalary(40);

            BaseEmployee contractEmployee = new ContractEmployee();
            var CteSalary = contractEmployee.CalculateSalary(40);
        }
    }

    public abstract class BaseEmployee
    {
        public string EmployeeID { get; set; }
        public string EmployeeName { get; set; }
        public string EmployeeAddress { get; set; }

        public abstract double CalculateSalary(int hoursWorked);
    }

    public class FullTimeEmployee : BaseEmployee
    {
        public override double CalculateSalary(int hoursWorked)
        {
            return hoursWorked * 60.00+3700;
        }
    }

    public class ContractEmployee : BaseEmployee
    {
        public override double CalculateSalary(int hoursWorked)
        {
            return hoursWorked * 65.00;
        }
    }
}

Following are few properties of Abstract class:

  • Abstract class can HAVE constructor even though it cannot be initiated, this constructor can be used to initiate common properties, e.g., GUID for each derived class.
  • Abstract class constructor is automatically called by derived class constructor (Parent class constructor is called first followed by child class constructor)
  • Since Abstract class constructor can only be called by derived class, constructor access modifier as Public does not make sense, it should be Protected.
  • Abstract function can be called from Abstract class constructor, whenever instance of derived class is created, overridden abstract method in derived class would be called.

History

  • 3/19/2015: Created
  • 3/20/2015: Added code snippets

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Architect
United States United States
A Solutions Architect with more than fourteen years of experience in application development. I mostly work in .NET, Angular, MEAN stack technologies and love to share what I do and learn during my day to day job. Please check my tutorials and blog:
https://fullstackhub.io
https://fullstackhubblog.com

Comments and Discussions

 
QuestionDoubt Pin
Member 145235307-Jul-19 14:04
Member 145235307-Jul-19 14:04 
QuestionAn imporvement Pin
Eric_Hobbs23-Mar-15 7:38
Eric_Hobbs23-Mar-15 7:38 
AnswerRe: An imporvement Pin
Yaseer Mumtaz23-Mar-15 7:52
professionalYaseer Mumtaz23-Mar-15 7:52 
AnswerRe: An imporvement Pin
ArchAngel12323-Mar-15 11:35
ArchAngel12323-Mar-15 11:35 
In this context, the IEmployee interface I'd superfluous - the abstract Employee class is itself an interface - no useful reason to also create the IEmployee in this case and it's one less thing in the code set to maintain and trace
GeneralConstructors order Pin
sashadu20-Mar-15 12:15
sashadu20-Mar-15 12:15 
GeneralRe: Constructors order Pin
Yaseer Mumtaz21-Mar-15 9:44
professionalYaseer Mumtaz21-Mar-15 9:44 
QuestionReal-Time?? Pin
Rob Grainger20-Mar-15 2:35
Rob Grainger20-Mar-15 2:35 
AnswerRe: Real-Time?? Pin
Yaseer Mumtaz20-Mar-15 5:43
professionalYaseer Mumtaz20-Mar-15 5:43 
GeneralRe: Real-Time?? Pin
Victor Ebe28-Oct-15 0:20
Victor Ebe28-Oct-15 0:20 
QuestionA few things to consider... Pin
Afzaal Ahmad Zeeshan19-Mar-15 23:12
professionalAfzaal Ahmad Zeeshan19-Mar-15 23:12 
AnswerRe: A few things to consider... Pin
Yaseer Mumtaz20-Mar-15 3:18
professionalYaseer Mumtaz20-Mar-15 3:18 
SuggestionA good one Pin
Arkadeep De19-Mar-15 20:40
professionalArkadeep De19-Mar-15 20:40 
QuestionA code example would be nice. Pin
Brady Kelly19-Mar-15 19:50
Brady Kelly19-Mar-15 19:50 
AnswerRe: A code example would be nice. Pin
Afzaal Ahmad Zeeshan19-Mar-15 23:01
professionalAfzaal Ahmad Zeeshan19-Mar-15 23:01 
GeneralRe: A code example would be nice. Pin
Brady Kelly19-Mar-15 23:27
Brady Kelly19-Mar-15 23:27 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.