程序类中的抽象方法与静态方法

时间:2013-06-25 16:16:04

标签: c# visual-studio-2010

假设我有一个简单的继承链,Employee是抽象基类,CheckoutManager在这个纯粹的说明性控制台应用程序中继承。现在我希望有一个方法可以接受类型为ManagerCheckout的对象,并根据员工公司中的位置返回整数奖金。我有一些初步的想法,如果这个控制台应用程序有一天成长为一个数据驱动的Web应用程序,我想知道每种方法的潜在长期缺陷或收益。

  1. 使用继承类的通用接口。 我的基类看起来像

    abstract class Employee
        {
            public int EmployeeId { get; set; }
            public string FirstName { get; set; }
            public string LastName { get; set; }
    
    
        }
    

    我的派生类实现了一个界面,用于将员工信息打印到名为IPrintable的控制台,并且只有一种方法可以执行此操作。虽然这个界面与赠送奖金无关,但我在课堂上用Main方法嘲笑了以下内容并且程序正常运行。

    static int GiveBonusesViaInterface(IPrintable i)
            {
                if (i is Checkout)
                    return 1000;
                else 
                    return 2000;
    
    
            }
    

    在我看来,如果我想为此使用一个界面,我应该制作另一个专门用于加注而不是在已经实现的界面上使用它(但这是另一天的另一个问题)。

  2. 在基类中使用静态方法,如

    public static int GiveBonus(Employee e)
            {
                if (e is Manager)
                    return 2000;
                else
                    return 1000;
            }
    
  3. 在抽象基类中创建一个抽象方法,并在他们认为合适的情况下实现nave派生类

    abstract class Employee
    //fields and constructors
    {
    public abstract int GiveBonusesViaAbstractMethod(Employee e); 
    }
    
  4. 这对我来说似乎是最糟糕的想法,因为在每个派生类中都必须有一个方法,它接受IPrintableEmployee类型的参数,而在Manager类中我们会必须测试员工is-a经理。

    对于长期Web应用程序,1-2是否具有可扩展性和可管理性?选项3真的和我做的一样糟糕吗?

4 个答案:

答案 0 :(得分:5)

你错过了传统的OO方式:

abstract class Employee {
    public int EmployeeId { get; set; }
    public string FirstName { get; set; }
    public string LastName { get; set; }
    public abstract int GetBonusAmount();
}

class Manager : Employee {
    public override int GetBonusAmount() { return 2000; } 
}

class Checkout : Employee {
    public override int GetBonusAmount() { return 1000; } 
}

Console.WriteLine(someEmployee.GetBonusAmount());

答案 1 :(得分:3)

我认为你们已经回答了自己的问题。

  

我的派生类实现了一个界面,用于将员工信息打印到名为IPrintable的控制台,并且只有一种方法可以执行此操作。虽然这个界面与赠送奖金无关

[强调我的]

你已经拥有了这个界面。它被称为Employee。惯用的方法是在抽象类上实现虚方法,并在必要时覆盖。更惯用的C#方法是编写属性并覆盖它。像这样:

abstract class Employee {
  public virtual int GetBonus()
  {
    return this.Bonus;
  }

  public virtual int Bonus { get; set; }
}

class Manager : Employee {
  public override int Bonus 
  { 
    get { return 2000; }
  }
}

class Checkout : Employee {
  public override int Bonus
  {
    get { return 1000; }
  }
}

答案 2 :(得分:1)

在两个子类中实现GetBonus()方法。你应该完全避免做“是实例检查”。

答案 3 :(得分:0)

我认为摘要效果很好:

abstract class Employee
{
    public int EmployeeId { get; set; }
    public string FirstName { get; set; }
    public string LastName { get; set; }
    public abstract int GetVariableBonus();
}

class Manager {
    public int GetVariableBonus(){
         return 2000;
    }
}

class Employee{
    public int GetVariableBonus(){
         return 1000;
    }
}

这就是你需要的吗?