Prabhu Prabhu - 7 months ago 8
Java Question

How to simplify java code by moving from inheritance to composition

I wrote the bottom level classes of multilevel inherited class but confused how to combine them to a single program. Someone suggested me to use composition instead of inheritance, and someone suggested to use

enum
to create anonymous subclass instead of complex inheritance structure. How can we use composition in place of inheritance or use
enum
instead of the inheritance that I used? What Should I do to simplify problem and How should it be done?

I am using Java to write a code to calculate tax. I am having base class
TaxPayer
. Taxpayer can have multiple
incomeSource
. There can be many types of
TaxPayer
or
IncomeSource
. There can be many income headings for each income source which is used to calculate
taxableIncome
.
taxRate
will be different for different type of
taxPayer
and
taxableIncome
. Final result will be
taxRate
applied to
taxableIncome
.

Base class Taxpayer is defined as

public abstract class TaxPayer {
private List<IncomeSource> incomeSource;
double taxRate;
Address address;
other attributes here;

public Double getTaxRate(){
return 0.25; //default tax rate
}
}

public abstract class IncomeSource {
private String incomeSourceName;
private Double incomeHeading1, incomeHeading2, incomeHeading3, ...;
private Double taxableIncome = incomeHeading1 + incomeHeading2 - incomeHeading3;
}


There can be some subclass of
IncomeSource
with different income headings. Similarly tax payer type can be modeled into following inheritance structure

Base Class: Taxpayer
* IndividualPerson
* Male, Female, OldAge
* Business
* Bank, ITIndustry, HydroElectricIndustry
* TaxFree
* SocialOrganization, ReligiousOrganization, PoliticalParty etc.


The subclasses of
TaxPayer
generally modifies the
taxRate
to be applied to
taxableIncome
and sometimes changes
taxableIncome
with some logic. For an example:

abstract class IndividualPerson extends TaxPayer{
if (incomeSource.taxableIncome > 250000) taxRate = ratex;
if (incomeSource.taxableIncome > 500000) taxRate = ratey;
@override
public getTaxRate() {
return taxRate;
}
}
class Female extends IndividualPerson {
if (incomeSource.getNumberOfIncomeSource() > 1) taxRate = taxRate + rate1;
else taxRate = taxRate - rate2
if (address.isRural() = true) taxRate = taxRate - rate3;
if (attributeX = true) taxRate = taxRate + rate4;
if ("Some other attribute" = true) taxableIncome = taxableIncome - someAmount;
}


We have to check attributes of
Taxpayer
and
IncomeSource
to determine the
taxRate
. Sometimes,
taxableIncome
can be modified according to
taxPayer
type and other conditions.

I am confused how to combine bottom level classes together to make a useable code. Someone suggested me not to use complex multilevel inheritance, instead, use composition or
enum
to achieve the desired result with less complexity. How to do this? Please give answers with enough details for beginners to understand.

Answer

It is better change to composition. You can do like this to change from multiple inheritance or interface to composition

  1. Inheritance:

    Class A{ }
    Class B extends Class A{ }
    Class C extends Class B{ }
    
  2. Interface:

    Interface A{ }
    Interface B implements Class A{ }
    Class C implements Class B{ }
    
  3. Composition:

    class C{  
        A objA = new A();  
        B objB = new B();
    
        pubic void test(){  
            objA.doSomething();
        } 
        public void methodA(){ 
            objA.method();
        }
    }