2013-06-25 5 views
0

Скажем, у меня есть простая цепочка наследования, где Employee - это абстрактный базовый класс, а Checkout и Manager наследуют его в этом чисто иллюстративном консольном приложении. Теперь я хочу иметь метод, который будет принимать объект типа Manager или Checkout и вернуть целочисленную сумму бонуса в зависимости от позиции в компании сотрудника. У меня были некоторые первоначальные мысли по этому поводу, и я хотел бы знать потенциальные долгосрочные дефициты или выгоды от каждого подхода, если это консольное приложение должно было в один прекрасный день стать веб-приложением, управляемым данными.Абстрактный метод против статического метода в классе программы

  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. Сделать абстрактный метод в абстрактном базовом классе и неф производные классы реализуют, как они считают нужным

    abstract class Employee 
    //fields and constructors 
    { 
    public abstract int GiveBonusesViaAbstractMethod(Employee e); 
    } 
    

Мне кажется, это наихудшая идея, потому что в каждом производном классе должен быть метод, который принимает параметр IPrintable или Employee и в классе менеджера мы должны были бы проверить, есть ли у сотрудника is-a Manager.

Являются ли 1-2 одинаково масштабируемыми и управляемыми для долгосрочного веб-приложения? Действительно ли вариант 3 так же плох, как я это сделал?

+0

Я думаю, что существующий подход (с использованием интерфейса) лучше других –

+0

О, нет, это становится все хуже. Не распространяйте свою логику и определенно не ставьте ее в свой статический класс с помощью «Main». Написание статического метода в порядке, но поместите его в абстрактный класс Employee, если у вас должен быть метод вообще. –

ответ

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; } 
    } 
} 
+0

Является ли это более OO-подходом, чем статическим методом в базовом классе Employee? – wootscootinboogie

+0

Я не знаю, что я бы назвал это «больше OO», обязательно. Статический метод можно так же легко использовать. Вам просто нужно передать параметр «Employee» и использовать это вместо 'this'. –

+0

Мои первоначальные аргументы в пользу создания метода static заключались в том, что мне только когда-либо приходилось изменять возвращаемые значения (скажем, если бы логика стала более сложной) в одном месте. Будет ли это серьезной проблемой или что-то глупо беспокоиться? – wootscootinboogie

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()); 
+0

'public override int BonusAmount {get {return 1000;}}' –

+0

@SamIam Yep, абстрактное свойство будет здесь одинаково хорошо работать. Все зависит от реализации - если это динамическое или расчетное значение, я бы, вероятно, пошел бы с помощью метода. Не то, чтобы это имело значение, так как в любом случае это один и тот же код, просто стиль. –

1

Внедрите метод GetBonus() в обоих подклассах. Вам следует избегать выполнения «экземпляра» проверок вообще.

+0

Что не так с 'является экземпляром чеков' – wootscootinboogie

+2

@wootscootinboogie вам не нужно знать. Используйте систему типов. В этом весь смысл наследования и полиморфизма. –

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; 
    } 
} 

Это то, что вам нужно?

+0

, это по сути то же самое, но я решил сделать абстрактный метод статическим, так как мне нужно было бы только изменить возвращаемые значения в одном классе (базовом классе) и на всех унаследованных. – wootscootinboogie

+2

@woots Нарушает принцип открытого закрывания. Классы должны быть открыты для расширения, закрыты для модификации. – aquaraga