我有3个类,其中两个继承自1:
public class Employee {
private virtual double getBonus() { ... }
private virtual double getSalary() { ... }
}
public class Nepotism : Employee {
private double getBonus() { ... }
}
public class Volunteer : Employee {
private double getSalary() { ... }
}
所以问题是有时会有一个志愿者获得裙带关系奖金 - 有没有办法编写构造函数以允许覆盖/嵌套 base 类,如下所示:
Employee Bill = new Volunteer(new Nepotism());
我在想:
public class Volunteer : Employee {
private Employee _nest;
public Volunteer(Employee nest)
: base() {
_nest = nest;
// now what?
}
}
基本上我希望一些对象能够从两个类中获得覆盖。
我想避免编写覆盖方法以检查嵌套类。
getSalary() {
return (nest != null) ? nest.salary : salary; // I want to avoid this if I can
}
我该怎么做?我是在正确的轨道上吗?我离开了吗?
答案 0 :(得分:13)
您可能需要考虑使用Decorator Pattern而不是子类。
它提供了子类化的替代方法,当您需要向类的单个实例添加“多个”附加功能时,它非常有用,这正是场景。
答案 1 :(得分:4)
我认为你试图以一种不明智的方式使用继承。这种方法会产生一系列依赖性和古怪的业务规则,从而导致难以使用和维护的僵化体系结构。
如果计算员工工资取决于员工以及“奖金特质”,那么将所有三件事彼此分开会更好:
interface IBonusTrait
{
decimal ApplyBonus(Employee employee, decimal currentTotal);
}
class Employee
{
// ...
public decimal BaseSalary { get; set; }
public IList<IBonusTrait> BonusTraits { get; set; }
}
class SalaryCalculator
{
public decimal CalculateSalary(Employee employee)
{
decimal totalSalary = employee.BaseSalary;
foreach (IBonusTrait bonusTrait in employee.BonusTraits)
{
totalSalary = bonusTrait.ApplyBonus(employee, totalSalary);
}
return totalSalary;
}
}
答案 2 :(得分:0)
如果一个对象可以同时成为两个类,那么您可能需要重新考虑如何进行继承。
在我看来,如果志愿者有时可以获得裙带关系奖金,那么你的志愿者课程应该有一个getBonus()方法,而且这个方法确实属于基类。对于大多数志愿者来说,它会返回零,但偶尔也不会 - 这没有任何问题。
答案 3 :(得分:0)
Reed Copsey已经说过,Decorator Pattern是值得考虑的。
还有这个youtube video与你的情况非常相似(John Skeet正在展示它)。