Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Class inheritance with empty subclasses

Suppose I have a class modeling expense items, named Expense. We have transportation, food, and wage expenses. Let's say that all of the properties are the same, so there is only the one Expense class, with a "type" property. However, let's say I add a new type of expense, called training, and this requires some new fields about the type of training, location, and date occurred. Additionally, there are a couple new methods specific to this training expense. So at this point, I need to subclass the Expense class so that I can have a TrainingExpense class. As the subclass is now defining the type of expense, does this make it redundant to have a "type" property in the Expense base class? Should I now just subclass the Expense base class for every different type? Or should I just leave the "type" property in the base class and have it be redundant for any subclasses?

like image 447
blacktie24 Avatar asked Jan 07 '14 23:01

blacktie24


2 Answers

Instead of inheritance I would use composition here. Create a property say ExpenseExtension of type interface IExpenseExtension in the base class.

For the expense types that have extra properties/methods inherit from IExpenseExtension and add the extra properties/methods needed. In the TravelExpense case it will have a TravelExpenseExtension class that inherits from IExpenseExtension with the extra properties/methods you need.

In the base class instantiate the appropriate ExpenseExtension class based on the ExpenseType Property.

Using composition instead of inheritance here will make it more flexible.

I would also suggest you to create an enum with all the types and use it for the ExpenseType property.

Check below Url to read about composition vs inheritance:

http://lostechies.com/chadmyers/2010/02/13/composition-versus-inheritance/

From the link: Favoring object composition over class inheritance helps you keep each class encapsulated and focused on one task. Your classes and class hierarchies will remain small and will be less likely to grow into unmanageable monsters.

UPDATE: See below code example in C#:

public class Expense
{
    public string Food { get; set; }

    public ExpenseType Type { get; set; }

    private IExpenseExtension expenseExtension;

    public IExpenseExtension ExpenseExtension
    {
        get
        {
            if(expenseExtension == null)
            {
                // Logic to instantiate the correct Extension based on Type property.
                // You can use Factory design pattern or something like that for this as well.
            }

            return expenseExtension;
        }
    }
}

public interface IExpenseExtension
{

}

public class TrainingExpenseExtension : IExpenseExtension
{
    public string Location { get; set; }

    public void GetTrainingDetails()
    {

    }
}
like image 149
Adarsh Shah Avatar answered Sep 29 '22 11:09

Adarsh Shah


Another approach might be define an IExpense interface, and then implement, so all your "standard" behaviours are accessed through the interface and the special behaviours via the class. Composition approach like blacktie24's but inverted. All depends on how you are going to access the extra stuff.

like image 26
Tony Hopkinson Avatar answered Sep 29 '22 12:09

Tony Hopkinson