我正在定义一个接口来对两个不同的子类进行分组。每个类都实现了inherit方法,但每个类都需要不同的参数才能工作。
这是界面。
public interface Billable()
{
decimal Bill();
}
这是第一堂课
public class HourlyEmployee : Billable
{
public decimal Bill(int hoursWorked, decimal pricePerHour) { }
}
这是第二个
public class CommissionEmployee : Billable
{
public decimal Bill(decimal commisionPercentage) { }
}
正如您所看到的,从概念上讲,他们使用该方法来实现相同的功能,即为服务收费。这就是我最初考虑继承的原因,但似乎这不是最好的方法。
哪些其他选择可以使这些类彼此相关?
答案 0 :(得分:3)
这并没有直接回答你标题中的问题,但你确实要求其他替代方案......
您的界面是合同,保证您的类将具有返回小数的Bill()
函数。但这并不意味着您必须接受该方法中的参数。
这里每个类的构造函数接受参数。 Bill()
方法执行计算以返回适当的值。
public interface IBillable
{
decimal Bill();
}
public class HourlyEmployee : IBillable
{
private int hoursWorked;
private decimal pricePerHour;
public HourlyEmployee(int hoursWorked, decimal pricePerHour)
{
this.hoursWorked = hoursWorked;
this.pricePerHour = pricePerHour;
}
public decimal Bill()
{
return hoursWorked * pricePerHour;
}
}
public class CommissionEmployee : IBillable
{
private int commissionPercentage;
public CommissionEmployee(int commissionPercentage)
{
this.commissionPercentage = commissionPercentage;
}
public decimal Bill()
{
// do some calculation using commissionPercentage and return a value...
}
}
答案 1 :(得分:2)
不确定这是否是最佳方法,但我认为您使用界面的方法很好(我按照惯例称之为IBillable)。
但是您不应该尝试将计算所需的所有值作为接口方法中的参数来容纳,因为这会限制您的可扩展性,如果您遇到需要一个额外的账单计算值的新员工会怎样。接口是一个不应该改变的合同,希望永远。下面建议的方法没有这个问题。
一个建议是使用另一个类(比如说BillCalculator)并将Billable接口所需的不同参数移动到该类的属性。
public abstract class BillCalculator: IBillable
{
abstract decimal Bill();
}
public class HourlyBillCalculator: BillCalculator
{
public int HoursWorked { get; set; }
public decimal PricePerHour { get; set; }
public HourlyBillCalculator(int hoursWorked, decimal pricePerHour)
{
HoursWorked = hoursWorked;
PricePerHour = pricePerHour;
}
public override Bill()
{
// Calculate the Bill
}
}
public class CommisionBillCalculator: BillCalculator {
public decimal CommisionRate { get; set; }
public CommisionBillCalculator(decimal rate)
{
CommisionRate = rate;
}
public override Bill() {
// Calculate the Bill
}
}
对应的计算器类必须使用工厂模式或其他东西来实例化以满足需要。然后,只需调用Bill方法,它将使用实例属性来计算值。
这样可以让界面签名保持一致。
注意:语法可能已关闭,但希望您明白这一点。
答案 2 :(得分:0)
显然,您提出的建议会产生语法错误,因为接口的每个实现都应该实现其所有原型方法。根据定义,实现原型意味着具有相同的参数,这就是为什么您不能为同一方法提供多个参数的原因。 但是,您可以利用.NET 4.0中的可选参数introduced
所以你可以拥有类似this的东西。