问题描述:

namespace WebApplication1.Class

{

public class DailySalaryCalculator

{

public void Calculate()

{

}

}

public class WeeklySalaryCalculator : DailySalaryCalculator

{

public void Calculate()

{

}

}

public class MonthlySalaryCalculator : WeeklySalaryCalculator

{

public void Calculate()

{

//I want to execute Calculate() of Daily Salary Calculator here.

}

}

}

I want to call Calculate method of DailySalaryCalculator directly From MonthlySalaryCalculator without creating a object of DailySalaryCalculator.

How can I do that?

Thanks in Advance

网友答案:

Your code is the improper use of inheritance. First of all, you need to understand what you're trying to accomplish, in this case you want to calculate salaries. Daily, Weekly or Monthly are strategies for doing the calculation.

You should consider each class an encapsulation of the business rule used to implement the calculations. Weekly makes no design sense to inherit from Daily, the same is for Monthly and Weekly.

The better way is this

public abstract AbstractSalaryCalculator
{
     //note that the calculation returns something, as this is basically a service
     public virtual decimal Calculate();
 }

 public class DailySalaryCalculator:AbstractSalaryCalculator
 {
    public override decimal Calculate()
    {
         //do stuff
        //return result
    }
 }

 public class WeeklySalaryCalculator:AbstractSalaryCalculator
 {
       public override decimal Calculate()
    {
         //do stuff
        //return result
    } 
 }

public class MonthlySalaryCalculator:AbstractSalaryCalculator
 {
     //probably is better for the daily calculator to be injected via the constructor
     public override decimal Calculate(DailySalaryCalculator daily)
    {
         //use daily to do stuff
        //return result
    } 
 }

var daily= new DailySalaryCalculator();
var monthly=new MonthlySalaryCalculator();
var result=monhtly.Calculate(daily);

Explanation

The point is to define calculators that handle a specific aspect of the business rules and then (re)use them in a decoupled way. All are calculators but a Weekly is not a Daily. A Weekly/Monthly can use a Daily because this is the relation between these concepts.

Inheritance means the child is a more specific concept of the parent's. In your use case, there is nothing more specific, they're just different ways to calculate a salary. That's why in my code, the monthly calc makes use of the daily one, but it doesn't inherit from it.

网友答案:

You can achieve that by overriding the original Calculate() method that must be declared as Virtual (to allow overriding it in inheriting classes).

To keep the code of the original method and add something to it, you should use the base keyword to call the original method's behavior.

Your code should look as follows :

namespace WebApplication1.Class
{
    public class DailySalaryCalculator
    {
        public virtual void Calculate()
        {
        }
    }

    public class WeeklySalaryCalculator : DailySalaryCalculator
    {
        public override void Calculate()
        {
        }
    }

    public class MonthlySalaryCalculator : WeeklySalaryCalculator
    {
        public override void Calculate()
        {
            //I want to execute Calculate() of Daily Salary Calculator here.
            //Yes do this :

            base.Calculate();

            //Now, Add your additional code here
        }
    }
}

Note !! : that you don't need to re-write the keyword virtual in the WeeklySalaryCalculator's Calculate() method, as this answer explains well :

You can declare a certain method as virtual only once, but you can override it as many times as you want - an override is not final, and it does not limit classes that inherit from the first overriding class.

网友答案:

You can achieve it by below code snippet,

Just cast the current object with DailySalaryCalculator class

public class DailySalaryCalculator
{
    public void Calculate()
    {

    }
}

public class WeeklySalaryCalculator : DailySalaryCalculator
{
    public void Calculate()
    {

    }
}

public class MonthlySalaryCalculator : WeeklySalaryCalculator
{
    public void Calculate()
    {
        (this.MemberwiseClone() as DailySalaryCalculator).Calculate();
    }
}

I am not sure what have you tried.

But below is working sample code for me.

class Program
{
    private static void Main(string[] args)
    {
        MonthlySalaryCalculator obj = new MonthlySalaryCalculator();

        obj.Calculate();

        Console.Read();
    }
}

public class DailySalaryCalculator
{
    public void Calculate()
    {
        Console.WriteLine("DailySalaryCalculator");
    }
}

public class WeeklySalaryCalculator : DailySalaryCalculator
{
    public void Calculate()
    {
        Console.WriteLine("WeeklySalaryCalculator");
    }
}

public class MonthlySalaryCalculator : WeeklySalaryCalculator
{
    public void Calculate()
    {
        (this.MemberwiseClone() as DailySalaryCalculator).Calculate();
    }
}
相关阅读:
Top