【发布时间】:2017-02-22 22:08:37
【问题描述】:
这是一个树结构的愚蠢示例,其中每个节点都执行不同类型的操作,但恰好一个节点(任何节点)必须在项目开始和结束时执行一些共同的工作。
public abstract class Employee
{
public void StartProject()
{
AnnounceProjectToNewspapers();
DoActualWork();
PutProductOnMarket();
}
protected abstract void DoActualWork();
private void AnnounceProjectToNewspapers() { }
private void PutProductOnMarket() { }
}
public class Engineer : Employee
{
protected override void DoActualWork()
{
// Build things.
}
}
public class Salesman : Employee
{
protected override void DoActualWork()
{
// Design leaflets.
}
}
public class Manager : Employee
{
protected override void DoActualWork()
{
// Make gantt charts.
// Also delegate.
foreach (var subordinate in subordinates)
// ...but then compiler stops you.
subordinate.DoActualWork();
}
private List<Employee> subordinates;
}
问题是,您不能在基类上调用受保护的方法DoActualWork()。
我看到的两个解决方案是:
-
将
DoActualWork()公开。 但这将允许任何人在没有AnnounceProjectToNewspapers()或PutProductOnmarket()的情况下调用它。 -
将
DoActualWork()设为内部。但这会阻止其他程序集使用“管理系统”。
是否有人们用来避免这种限制的标准变通方法?
【问题讨论】:
-
你说的“你不能在基类上调用受保护的方法
DoActualWork()”是什么意思。到目前为止,您的设计是常见的做法,我认为它没有问题。 -
如果我理解正确,您需要将 DoActualWork 设为 Manager 类私有,同时外部调用者也可以使用。这有点令人困惑,因为它与继承的抽象原则相矛盾。我认为您需要将工作实现分离到一个单独的类中,我们将其称为 Task 并根据需要使其成员公开/私有。
-
@OndrejTucny 受保护的成员只能通过为派生类的静态类型或派生类型的对象调用派生类来访问。所以
Manager不能调用subordinate.DoActualWork(),因为从属不是Manager或派生自它。 -
@IslamYahiatene 我想让
DoActualWork“私有”到Employee类和所有从它派生的类,但仍然允许派生类覆盖它。 -
Manager类需要访问Employee类的从属实例的DoActualWork方法的实现。这意味着DoActualWork需要为public或至少为internal。随着您当前的设计试图实现您想要的目标,这将是一些“hacky”的解决方法。
标签: c# oop polymorphism