Inheriting classes with empty subclasses

Suppose I have a class that models expense items called Expense. We have the cost of transportation, food and wages. Let's say that all properties are the same, so there is only one Expense class with a type property. However, let me say that I am adding a new type of expense called training, and this requires new fields regarding the type of training, location and date. In addition, there are several new methods specific to this learning expense. So for now, I need to subclass the Expense class so that I have the TrainingExpense class. Since the subclass now determines the type of expense, does the "type" property in the Expense base class make this redundant? Should I now just subclass the Expense base class for every other type? Or should I just leave the "type" property in the base class and have it redundant for any subclasses?

+6
source share
2 answers

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

For expense types that have additional properties / methods, they inherit from IExpenseExtension and add additional properties / methods as needed. In the case of TravelExpense, it will have the TravelExpenseExtension class, which inherits from IExpenseExtension the additional properties / methods that you need.

In the base class, create an instance of the corresponding ExpenseExtension class based on the ExpenseType property.

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

I also suggest that you create an enumeration with all types and use it for the ExpenseType property.

Check below Url to read about composition and inheritance:

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

From the link: Approving object composition over class inheritance helps keep each class encapsulated and focused on one task. Your classes and class hierarchies will remain small and less likely to turn into uncontrollable monsters.

UPDATE: The following is an example of C # code:

 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() { } } 
+6
source

Another approach could be to define an IExpense interface and then implement it, so all of your โ€œstandardโ€ behaviors are accessible through the interface and special behaviors through the class. A compositional approach, like blacktie24, but upside down. It all depends on how you are going to access additional materials.

+1
source

All Articles