【问题标题】:Confusion regarding inheritance based on examples基于示例的关于继承的困惑
【发布时间】:2019-10-26 15:13:12
【问题描述】:

有时我经常对何时派生类(使用继承)和何时不派生感到困惑。例如,我有这样的代码:

public class Payroll
{
    public void ProcessPayroll(Employee e) //abstraction
    {
         e.ProcessPayroll();
    }
}

Class Employee : Payroll
{
    public virtual void ProcessPayroll()
    {
       //Process Payroll
    }
}

class FulltimeEmployee : Employee
{
    public override void ProcessPayroll()
    {
       //Payroll processing based on fulltime employee
    }
}

这是有道理的:

class FulltimeEmployee : Employee

因为FulltimeEmployee is a Employee 所以IS-A relationship 在这里成立。

但是我在这里对以下关系感到困惑,因此这种继承是否有意义,因为它不是 "IS-A" relationship

Class Employee : Payroll

继承总是必须遵循 IS-A 关系?

另一个例子:

要求说“没有公司,员工就不能存在”

基于此,我这样做了:

public class Company

public class Employee : Company

现在这有意义吗?

更新:

我认为使用Aggregation 可以更好地表示上述内容:

public class Company
{ 
    Employee E; //because Company has-a Employee
}

但是明天如果要求说公司也可以在没有员工的情况下存在,这意味着我必须来这个课程并更新代码。

这不是违反Open and Closed principle吗?

【问题讨论】:

  • 员工不是工资单。那里应该没有继承关系。员工可能工资单上,但这不是一回事。
  • EmployeePayroll 的特殊类型吗?听起来不是这样。
  • 继承是一种“IS-A”关系。类(实现)继承是一种特殊情况——Java 中也有可能更适合的接口。 “员工是公司”或“员工是工资单”没有意义。
  • @AndyTurner 是的,你是对的,但 Employee 是工资核算流程的一部分。所以我想了解 Is-A 关系是否对继承是强制性的

标签: c# oop inheritance aggregation


【解决方案1】:

要求说“没有公司,员工就不能存在”,这意味着公司有员工。 Has-A 关系也称为组合。 您不需要此类员工:工资单。它应该只是 Employee 类。

在 Payroll 类中,Employee 对象被注入,因此它可以处理即时方法。 同样为了良好的做法,请遵循Prefer composition over inheritance?

更新部分的答案: Open close principal 说“类对扩展开放但对修改关闭”

public class Company
    {
        private readonly IEmployee e;
        public Company(IEmployee e)
        {
            this.e = e;
        }
    }
    public interface IEmployee
    { //Some employee related methods
    }

在这里,您在 Company 类中注入了 IEmployee。现在您可以使用 IEmployee 的 Instant 扩展 Company 类功能。 查看策略模式示例,希望能澄清您的疑问Real World Example of the Strategy Pattern

【讨论】:

  • 明天如果要求说公司可以在没有员工的情况下存在而不是如何在您的代码中处理此要求?
  • @ILoveStackoverflow:在这种情况下,只需从您要注入的公司类中删除 Employee。
【解决方案2】:

你说的是HAS-A关系,所以你需要组合:

public class Employee
{
  Payroll payroll;
  Company company;
  ...
}

因为每个员工都在某个地方被雇用,所以它有一个他工作的公司。

另一方面,公司有员工,因此可以这样设计:

public class Company
{
  List<Employee> employees;
  ...
}

您还需要为Employee 没有Company 的情况做好准备,反之亦然,那么类中的各个字段将是null,考虑到这一点,您需要编写带有null 检查的方法处理这种情况,例如:

if(employees == null || employeses.Count == 0)
  Console.WriteLine("Sorry, company has no employees!");

【讨论】:

  • 但是明天如果要求说Company可以在没有Employee的情况下存在,那么我必须来Company类并更新代码。这是否违反了Open/Closed原则?
  • @ILoveStackoverflow 那么公司应该有employees = null 并且在使用employees 的函数中,当此字段为null 时,您应该处理大小写。有了这样的设计,它就会被关闭以供修改。
  • 你能在代码中告诉我,如何在不违反开放/封闭原则的情况下正确处理这两个要求。
猜你喜欢
  • 1970-01-01
  • 2011-12-18
  • 2019-11-07
  • 1970-01-01
  • 2012-04-10
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多