【问题标题】:How to Implement class composition with inheritance in C#如何在 C# 中使用继承实现类组合
【发布时间】:2023-03-24 01:57:01
【问题描述】:

我是面向对象开发的新手,感谢您在这方面的帮助。 在我的工资系统中,我有四个类别,分别称为“支付”、“工资”、“收入”和“扣除”。 准备工资需要多种类型的收入(如加班费、奖励、空间津贴、额外班次支付、预算津贴、预付金额等)和扣除(如保险、制服、贷款、恢复、福利、膳食、预支工资等) .) 因此,我将其分为两类,即“收入”和“扣除”。最后,“Salary”类应该做平衡部分,“payment”类将处理支付部分(银行业务)。其他类型的付款是预支工资,这只是每月支付的金额。建模的关系如下…… “Earning”和“Deduction”类与“Salary”有组合关系,“Salary”是“Payment”的派生类。我已经在我的 C# 代码中实现了这些关系,如下所示…… 我的问题是

1.我是否以适当的方式关联类?

2.关系的实现是否正确?

付款

   class payment
    {
        public virtual void pay()
        {

        }
}

薪水

class salary:payment
{
//Composition of ‘Earning’ class
    private earning E1;

    public salary()
    {
        E1 = new earning(this);

    }
//Calling calEarning() of ‘Earning’ class through ‘Salary’ class
    public void calEarningForSal()
    {
        E1.calEarning();
    }

//Implementing pay method of base class 
    public override void pay()
    {

    }

}

收入

  public class earning
    {
    //Since earning has a composition relationship with salary…
        private salary S1;

        internal earning(salary sal)
        {
            this.S1 = sal;
        }
    //This method will calculate earnings of employees
        public void calEarning()
        {

        }
    }

主要方法

Main()
        {
            salary newSal = new salary();
            newSal.calEarningForSal();
        }

【问题讨论】:

  • 这取决于你想要什么。照常。我没有在这里得到“收入”和“扣除”的预期作用。
  • 但是 Salary IS-A 付款听起来令人怀疑。如果工资分两部分支付怎么办?
  • 我同意@HenkHolterman,我开始回答这个问题,然后意识到SalaryEarning 之间的歧义 - 你需要澄清每个班级的角色。
  • @Henk Holterman,实际上在这种情况下,准备工资需要多种类型的收入(如加班、激励、空间津贴、额外班次支付、预算津贴、预付金额等)和扣除(比如保险、制服、贷款、康复、福利、膳食、预支工资等)所以我把它分成两个类别,即“收入”和“扣除”。最后,“薪水”类应该做平衡部分,“支付”类将处理支付部分(银行业务)。其他类型的付款是预支工资,这只是每月支付的金额。谢谢!

标签: c# uml composition


【解决方案1】:

在尝试确定是使用组合还是聚合时,要问的简单问题是

  • A 是否属于 B
  • A 是否使用 B

在你的情况下,你说

‘Earning’和‘Deduction’类与‘Salary’有构成关系

所以通俗地说,你所说的是Earning/Deduction属于一个Salary,换句话说,一个Salary组成的 一个Earning/Deduction(以及许多其他组件)。话虽如此,我希望您的 Salary 课程看起来像

public class Salary
{
    private Earning e;
    private Deduction d;

    public Salary()
    {
        this.e = new Earning();
        this.d = new Deduction();
    }

    public void override Pay()
    {
        ... 
    }
}

Earning/Deduction 不应该知道Salary,这些类实际上是构成Salary 的组件。例如,您的 Earning 类可能看起来像

public class Earning
{
    public Earning()
    {
    }

    public void Calculate()
    {
        ...
    }
}

如果Earning/Deduction 需要来自 Salary 的信息,那么您可以传递此信息,但是,您不应传递对 Salary 本身的引用,因为这会破坏组合关系(实际上在Earning/Salary 之间引入了聚合)。


在继承方面,如果基类 Payment 只提供简单的 Pay 方法,那么我建议使用接口代替,例如

public interface IPayable
{
    void Pay();
}

public class Salary : IPayable
{
    ...
}

【讨论】:

  • 先生,实际上 Payment 类还有一些方法,例如 makeSummary()、viewPayment()、viewPaymentHistory()、bank() 等。请查看给@Henk Holterman 的评论以获取更多详细信息。谢谢!
  • @Chathur 很好,你不需要使用界面建议。如果 Salary 实际上是由 multiplesEarning/Deduction 组成,那么我将只为两者维护一个内部列表 - 将 Salary 传递给它仍然没有意义Earning/Deduction.
猜你喜欢
  • 2021-11-25
  • 2012-08-27
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-03-25
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多