从基类获取对对象的引用。装饰设计模式

时间:2019-01-08 10:00:51

标签: c# oop design-patterns composition

我正在处理Decorator design pattern。我现在得到的是:

我的基础abstract class Worker

public abstract class Worker
{
    public float UsdPerHour { get; set; }
    public int HoursPerDay { get; set; }
    public int DaysOfWork { get; set; }

    public abstract float CountSalary();
}

它是抽象的,因为它是我的Workers类的基础。我认为这不是必需的,那一类是什么。如果您愿意,我会将其添加到我的编辑中。

接下来,我开始实现我的装饰器。每个WorkerCountSalary()。我想根据装饰员将奖金应用到他们的工资中。

我们从abstract Bonus类开始:

public abstract class Bonus : Worker
{
    public Bonus(Worker worker) => this.worker = worker;
    public override float CountSalary() => worker.CountSalary();

    private Worker worker { get; set; }
}

奖励是AmountBonus类的基本要求。

public class AmountBonus : Bonus
{
    public AmountBonus(Worker worker) : base(worker: worker){ }
    // is this 'base' call correct?

    public override float CountSalary()
    {
        throw new NotImplementedException();
    }

    private Worker worker;
}

我的问题是,如何在具体装饰器类的基类(Worker worker)中将对象Bonus引用为AmountBonus

编辑

在您的帮助下,我可以从private Worker worker类中删除AmountBonus,并像worker那样从基础Bonus类中玩base.worker吗?有可能吗?

enter image description here

VS没有告诉我,这是不允许的

public override float CountSalary() => base.worker.CountSalary();

1 个答案:

答案 0 :(得分:1)

通过将您的private Worker worker { get; set; }变成外部的protected Worker worker { get; set; }类无法访问它,但是基类可以访问它。即使基类为abstract

,此方法也有效

编辑:这也是学习C#命名约定的好时机;)MSDN docs
编辑2:正如this注释所指出的,您可能想在private set中使用Worker worker

在问题后进行编辑编辑:您仍然(仅在需要时)需要Bonus类中的Worker,但是不需要再次声明private Worker worker;,因为(由intellisense正确指出)隐藏了Bonus.worker工作程序。如果Bonus.Worker设置为protected而不是private,则可以从继承的类中使用它,而无需再次声明。结果将是:

public abstract class Worker
{
    public float UsdPerHour { get; set; }
    public int HoursPerDay { get; set; }
    public int DaysOfWork { get; set; }

    public abstract float CountSalary();
}

public abstract class Bonus : Worker
{
    public Bonus(Worker worker) => this.worker = worker;
    public override float CountSalary() => worker.CountSalary();

    protected Worker worker { get; private set; }
}

public class AmountBonus : Bonus
{
    public AmountBonus(Worker worker) : base(worker: worker){ }

    public override float CountSalary()
    {
        throw new NotImplementedException();
    }
}