【问题标题】:Some trouble with private abstract methods私有抽象方法的一些问题
【发布时间】:2012-08-12 21:16:28
【问题描述】:

假设我开设了一个主要课程Car - 我希望这个课程是抽象的。抽象因为这是我的主要课程,没有人应该成为这个课程的对象。这个类应该只作为“骨干”存在。

我希望只能从Car 的子类创建类(比如说梅赛德斯、法拉利……)。因为每辆车都应该有StartEngine这样的方法,所以我把它放到了major class。假设我有这个:

abstract class Car
{
  public string Name { get; set; }

  public abstract void StartEngine();
  private abstract bool CheckGasoline();
  //and so on...
}

class Mercedes : Car
{
  private override bool CheckGasoline()
  {
  //somehow check gasoline and return whatever...
  }

  public override void StartEngine()
  {
    if (CheckGasoline())
      //start engine...
  }
}

这行不通。由于私人摘要:

virtual or abstract members cannot be private

所以我要保护每个私有方法:

abstract class Car
{
  public string Name { get; set; }

  public abstract void StartEngine();
  protected abstract bool CheckGasoline();
  //and so on...
}

class Mercedes : Car
{
  protected override bool CheckGasoline()
  {
  //somehow check gasoline and return whatever...
  }

  public override void StartEngine()
  {
    if (CheckGasoline())
      //start engine...
  }
}

这样好吗?我的意思是它正在工作,但它应该是这样吗?当我只需要同一个类中的方法时使用 protected (比如这里:CheckGasoline() 只需要 StartEngine() )。不知何故,私人会更好看。

有什么建议吗?谢谢。

【问题讨论】:

  • 你也可以考虑使用接口代替抽象类。 IE。在您的示例中Tesla 将不得不加入CheckGasoline 并混淆您的基类...
  • 通过使其抽象化,您已经决定每个后代都应该覆盖它,因此它不能是私有的。如果您想对实现进行更多控制,那么接口,甚至可能是事件的聚合 OnCheckGas(object sender, out int percent) 将是可行的方法
  • Thx,但是我仍然没有“感觉”,当使用抽象类或接口要好得多。
  • @miri 这本身就是一个问题:)。 This article 提供了一些非常有用的提示。

标签: c# .net abstract-class


【解决方案1】:

是的,这很好。子类型看不到私有方法,因此不能override它们:它们必须protected(或公共等)。 c# 中没有“方法 X 的私有”之类的东西,所以它必须按原样满足。

【讨论】:

    【解决方案2】:

    Private methods 不能被除它们所在的类之外的任何类访问 - 这包括派生类。

    另一方面,Protected methods 可以被它们所在的类和它们的派生类访问。

    您对 protected 的使用是正确的。

    您可能会发现这篇文章对您有所帮助:http://msdn.microsoft.com/en-us/library/ba0a1yw2(v=vs.80).aspx

    【讨论】:

      【解决方案3】:

      您可以构建覆盖挂钩。微软通过FrameworkElement.ArrangeCore(...)(使用ArrangeOverride)和FrameworkElement.MeasureCore(...)(使用MeasureOverride)来做到这一点。

      例如:

      abstract class Car
      {
        public string Name { get; set; }
      
        public void StartEngine()
        {
          if (CheckGasoline())
              StartEngineOverride();
        }
      
        protected abstract void StartEngineOverride();
        protected abstract bool CheckGasoline();
      
        // ...
      }
      
      class Mercedes : Car
      {
        protected override bool CheckGasoline()
        {
           //somehow check gasoline and return whatever...
        }
      
        protected override void StartEngineOverride()
        {
           // CheckGasoline was already checked, so just do the override portion.
        }
      }
      

      【讨论】:

        【解决方案4】:

        我推荐以下:

        尝试在抽象类中对成员变量声明使用protected。然后将public 也用于您的抽象方法。

        接下来,在您的派生类中,您应该对派生类中的方法使用 public 和 override。但是,这是您拥有的另一种选择,即您也可以使用 virtual。因此,不要使用单个抽象类,而是将所有潜在的 Car 类型类嵌套在一个公共 CarClass 类中,或者任何你想调用的类中。

        在第一个声明的类(Abstract Car)中为共享方法使用虚方法。然后对嵌套在 CarClass 类中的其余声明的派生类使用公共覆盖,它可以覆盖您在 asbstract Car 类中声明的虚拟方法。这是您拥有的另一个选项,尽管它可能会将您限制为仅在 CarClass 中声明的任何内容,而不是一个独特且单独的抽象类。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2015-10-26
          • 1970-01-01
          • 2015-06-26
          • 1970-01-01
          • 2011-03-28
          • 2011-02-21
          • 2015-02-09
          相关资源
          最近更新 更多