强制继承类调用基本辅助方法

时间:2014-03-17 16:17:48

标签: c# oop

我有一个包含辅助方法的基类。如何强制继承类调用此帮助器方法?有没有办法警告消费者必须调用GenerateId?我应该将这个帮助方法作为基础构造函数逻辑的一部分吗?

例如:

public class FooBar
{
    public int GenerateId(string productCode)
    {
       //..some logic to return an integer;
    }
}
public class AnotherFooBar : FooBar
{
    public void Save()
    {
       var fooBarId = this.GenerateId("myproduct");
       //fooBarId will be used in this code block
    }
}

4 个答案:

答案 0 :(得分:4)

您可以这样做:

    public abstract class FooBar
    {
        public void Save()
        {
            var fooBarId = this.GenerateId("myproduct");
            SaveCore(fooBarId);
            //fooBarId will be used in this code block
        }

        protected abstact void SaveCore(int id);
    }

现在强制子类在调用Save时调用该方法。我不知道SaveCore是否需要id,如果是,你可以将它作为样本中的参数传递。

之后,如果不需要,您可以将GenerateId设为私有,因为它看起来似乎不是您希望让人们可以自由做的事情。

无论如何,请考虑很好地记录SaveCore和id代表什么,因为继承会增加实现的复杂性,并且子类可能以错误的方式实现。

答案 1 :(得分:3)

您可以使基类抽象化并强制派生类实现方法。放置必须在基类中调用GenerateId()的方法,并让它调用抽象方法:

public abstract class FooBar
{
    protected abstract string Product { get; }

    private int GenerateId(string productCode)
    {
       //..some logic to return an integer;
    }

    public void Save()
    {
       var fooBarId = this.GenerateId(Product);
       SaveInternal(fooBarId);
    }

    protected abstract void SaveInternal(int id);
}

public class AnotherFooBar : FooBar
{
    protected override string Product { get { return "myproduct"; } }

    protected override void SaveInternal(int id)
    {
       // id will be used in this code block
    }
}

此外,由于派生类可能希望为不同的产品生成ID,因此也要在基类中创建一个抽象的只读Product属性,从而强制派生类提供产品名称。

答案 2 :(得分:2)

您无法在重写方法上“强制执行”任何操作。你是从错误的角度看待这个。

请参阅Martin Fowler's Article有关正确方法的信息。

基本上,如果您的基类需要在每次调用覆盖时执行特定代码,那么您应该只覆盖基本方法的“部分”,如下所示:

class A
{
   void MethodOne()
   {
      //Here you perform your obligatory logic.

      //Then, call the overridable logic.
      MethodOneCore();
   }

   virtual void MethodOneCore()
   {
      //Here you perform overridable logic.
   }
}

class B: A
{
   override void MethodOneCore()
   {
      //Here you override the "core" logic, while keeping the obligatory logic intact.
   }
}

答案 3 :(得分:0)

这是你要找的吗? (你的问题不完全清楚......)

public class FooBar
{
    public abstract int GenerateId(string productCode);

    public void Save()
    {
       var fooBarId = this.GenerateId("myproduct");
       //fooBarId will be used in this code block
    }
}
public class AnotherFooBar : FooBar
{
    public override int GenerateId(string productCode)
    {
       //..some logic to return an integer;
    }
}