2013-06-25 114 views
0

假設我有一個簡單的繼承鏈,其中Employee是抽象基類,CheckoutManager在此純粹說明性的控制檯應用程序中繼承。現在我想擁有一個方法,它將接受ManagerCheckout類型的對象,並根據員工公司中的職位返回一個整數獎金。我對此有一些初步想法,並希望瞭解每種方法可能帶來的潛在長期不足或收益,如果這款控制檯應用程序有一天會成長爲數據驅動的Web應用程序。程序類中的抽象方法vs靜態方法

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

這對我來說似乎是最糟糕的想法,因爲在每個派生類中必須有一個方法,這個方法需要參數IPrintableEmployee類型和經理類中,我們必須測試員工is-a經理。

對於長期的Web應用程序,1-2是否具有可擴展性和可管理性?選項3真的和我一樣糟糕嗎?

+0

我認爲存在的方法(使用接口)比其他 – 2013-06-25 16:21:32

+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

這是比在Employee基類中創建靜態方法更OO的方法嗎? – wootscootinboogie

+0

我不知道我會把它稱爲「更多OO」,必然。靜態方法可以很容易地使用。你只需要傳遞一個'Employee'參數並使用它來代替'this'。 –

+0

我使得該方法是靜態的最初推理是我只需要在一個地方改變返回值(比如說邏輯變得更復雜)。這是一個有效的關注點,還是一些令人擔憂的事情? – 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是的,抽象屬性在這裏同樣適用。這一切都取決於實施 - 如果它是一個動態或計算值,我可能會採用一種方法。不過這並不重要,因爲無論如何它都是相同的代碼,只是風格而已。 –

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違反了Open Closed原則。類應該被打開以進行擴展,關閉以進行修改。 – aquaraga