2014-09-30 54 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"; 
    } 
} 
相关问题