I Love Stackoverflow
I Love Stackoverflow

Reputation: 6868

Confusion regarding inheritance based on examples

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 ?

Upvotes: 0

Views: 109

Answers (2)

Gopu_Tunas
Gopu_Tunas

Reputation: 194

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

Upvotes: 3

Michał Turczyn
Michał Turczyn

Reputation: 37500

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!");

Upvotes: 1

Related Questions