2014-09-30 83 views
4

假設你有一個類層次結構爲:如何修改所有派生類中的方法返回值?

class Base 
{ 
    public virtual string GetName() 
    { 
     return "BaseName"; 
    } 
} 

class Derived1 : Base 
{ 
    public override string GetName() 
    { 
     return "Derived1"; 
    } 
} 

class Derived2 : Base 
{ 
    public override string GetName() 
    { 
     return "Derived2"; 
    } 
} 

在最恰當的方式,我怎麼能寫在所有「的GetName」的方法增加了「XX」的字符串在派生類中返回值的方式的代碼?

例如:

  Derived1.GetName returns "Derived1XX" 

     Derived2.GetName returns "Derived2XX" 

更改GetName方法實現的代碼不是好辦法,因爲可能存在多個派生類型基地。

+0

這通常不是一個好的設計。如果你不想在孩子們身上改變某些東西,那就把它「封」起來。 – Renan 2014-09-30 21:08:46

+1

@Ranan方法默認是封閉的,它們必須是'virtual'才能被覆蓋。如果班級是「密封」的,那麼就不會有孩子。而OP確實希望'GetName'在每個孩子中都返回不同的東西 - 他只是想要一個通用的後綴。 – Blorgbeard 2014-09-30 21:14:35

+0

@Blorgbeard true.dat。我完全忘記了。 – Renan 2014-09-30 21:26:04

回答

7

請假GetName非虛擬,並將「追加XX」邏輯放在該函數中。將名稱(不帶「XX」)提取到受保護的虛擬函數,並覆蓋子類中的名稱。

class Base 
{ 
    public string GetName() 
    { 
     return GetNameInternal() + "XX"; 
    } 

    protected virtual string GetNameInternal() 
    { 
     return "BaseName"; 
    } 
} 

class Derived1 : Base 
{ 
    protected override string GetNameInternal() 
    { 
     return "Derived1"; 
    } 
} 

class Derived2 : Base 
{ 
    protected override string GetNameInternal() 
    { 
     return "Derived2"; 
    } 
} 
0

覆蓋可以調用它的基本函數...然後,您可以修改基類來追加所需的字符。

2

如果你不想(或不能)修改原來的類,你可以使用擴展方法:

static class Exts { 
    public static string GetNameXX (this Base @this) { 
     return @this.GetName() + "XX"; 
    } 
} 

您可以訪問新的方法和往常一樣:

new Derived1().GetNameXX(); 
3

這是裝飾者模式的一個很好的用例。創建具有在底座上的參考裝飾:

class BaseDecorator : Base 
{ 
    Base _baseType; 

    public BaseDecorator(Base baseType) 
    { 
     _baseType = baseType; 
    { 

    public override string GetName() 
    { 
     return _baseType.GetName() + "XX"; 
    } 
} 

構建Ba​​seDecorator與您所選擇的類(Base或派生),並調用的GetName上。

+0

這似乎是一個很好的解決方案。另一種可應用的模式是[策略模式](http://en.wikipedia.org/wiki/Strategy_pattern) – Steve 2014-09-30 21:12:11

1

您可以將名稱的構造拆分爲各種可覆蓋部分,然後覆蓋每個不同子類中的每個部分。 下面是一個這樣的例子。

public class Base { 
    public string GetName() { 
    return GetPrefix() + GetSuffix(); 
    } 
    protected virtual string GetPrefix() { 
    return "Base"; 
    } 
    protected virtual string GetSuffix() { 
    return ""; 
    } 
} 

public class DerivedConstantSuffix : Base { 
    protected override string GetSuffix() { 
    return "XX"; 
    } 
} 

public class Derived1 : DerivedConstantSuffix { 
    protected override string GetPrefix() { 
    return "Derived1"; 
    } 
} 

public class Derived2 : DerivedConstantSuffix { 
    protected override string GetPrefix() { 
    return "Derived2"; 
    } 
} 
相關問題