在c#中嵌套基类

时间:2010-06-24 18:43:32

标签: c# polymorphism

我有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
}

我该怎么做?我是在正确的轨道上吗?我离开了吗?

4 个答案:

答案 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正在展示它)。