By ILoveStackoverflow


2019-06-12 07:12:58 8 Comments

Sometimes I get often confused between when to derive class(use inheritance) and when not to.So for instance I have a code like this :

public class Payroll
{
    public void ProcessPayroll(Employee e) //abstraction
    {
         e.ProcessPayroll();
    }
}

Class Employee : Payroll
{
    public virtual void ProcessPayroll()
    {
       //Process Payroll
    }
}

class FulltimeEmployee : Employee
{
    public override void ProcessPayroll()
    {
       //Payroll processing based on fulltime employee
    }
}

This make sense :

class FulltimeEmployee : Employee

Becuase FulltimeEmployee is a Employee so IS-A relationship holds true here.

But I am confused here for below relationship so as to does this inheritance make sense as it is not an "IS-A" relationship ?

Class Employee : Payroll

Also Inheritance always have to follow IS-A relationship ?

Another Example :

Requirement says "Employee cannot exist without Company"

Based on this I did this :

public class Company

public class Employee : Company

Now does this make sense ?

Update :

I think above can be better represented using Aggregation :

public class Company
{ 
    Employee E; //because Company has-a Employee
}

But tomorrow if requirement says Company can exist without Employee too that means I have to come to this class and update the code.

Isnt this will violate Open and Closed principle ?

2 comments

@Gopu_Tunas 2019-06-12 07:21:42

Requirement says "Employee cannot exist without Company" it means company has a employees. Has-A relationship is also known as composition. You don't require this Class Employee : Payroll. It should be just class Employee.

In Payroll class, Employee object is injected, so it can process on instant methods. Also for good practice follow this Prefer composition over inheritance?

Answer for updated part: Open close principal says "Class is open for extension but closed for modification"

public class Company
    {
        private readonly IEmployee e;
        public Company(IEmployee e)
        {
            this.e = e;
        }
    }
    public interface IEmployee
    { //Some employee related methods
    }

Here you have injected IEmployee in Company class. Now you can extend Company class functionality using instant of IEmployee. Look at Strategy Pattern example, which hopefully clarified your doubt Real World Example of the Strategy Pattern

@ILoveStackoverflow 2019-06-12 08:10:45

Tomorrow if requirements say that Company can exist without employees than how to handle this requirement in your code?

@Gopu_Tunas 2019-06-13 08:07:16

@ILoveStackoverflow: In that case, just remove Employee from company class where you are injecting.

@Michał Turczyn 2019-06-12 07:20:33

What you are talking is rather HAS-A relationship, so you need composition:

public class Employee
{
  Payroll payroll;
  Company company;
  ...
}

As every employee is hired somewhere, so it has a company he works at.

On the other side, company has employees, so it could be designed as well as:

public class Company
{
  List<Employee> employees;
  ...
}

You need to prepare yoursef also for situation where Employee has no Company or vice versa, then respective fields in classes would be null, Considering that, you need to write your methods with null checks to handle such situation, like:

if(employees == null || employeses.Count == 0)
  Console.WriteLine("Sorry, company has no employees!");

@ILoveStackoverflow 2019-06-12 07:26:56

But tomorrow if requirement says Company can exist without Employee too than I have to come to Company class and update the code.Isnt this violating Open/Closed principle?

@Michał Turczyn 2019-06-12 07:35:51

@ILoveStackoverflow Then company should have employees = null and in functions using employees you should handle case, when this field is null. With such design, it would be closed for modification.

@ILoveStackoverflow 2019-06-12 07:49:38

Can you show me in the code,How to handle both the requirement properly without violating Open/Closed principle please.

@Michał Turczyn 2019-06-12 07:57:10

@ILoveStackoverflow See update

Related Questions

Sponsored Content

28 Answered Questions

6 Answered Questions

[SOLVED] Python class inherits object

10 Answered Questions

[SOLVED] Calling the base constructor in C#

33 Answered Questions

[SOLVED] Prefer composition over inheritance?

25 Answered Questions

[SOLVED] Why not inherit from List<T>?

7 Answered Questions

[SOLVED] Examples of GoF Design Patterns in Java's core libraries

15 Answered Questions

7 Answered Questions

[SOLVED] Favor composition over inheritance

Sponsored Content