私有抽象方法有些麻烦

时间:2012-08-12 21:16:28

标签: c# .net abstract-class

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

我希望只能从Car的子类创建类(比如梅赛德斯,法拉利......)。因为每辆车都应该有类似StartEngine的方法,所以我将它放入大班。假设我有这个:

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())。以某种方式私人会看起来更好。

有什么建议吗?谢谢。

4 个答案:

答案 0 :(得分:25)

是的,没关系。子类型无法看到私有方法,因此无法override:他们必须protected(或公共等)。在c#中没有“私有到方法X”这样的东西,所以它必须足够原样。

答案 1 :(得分:8)

Private methods除了它们所在的类之外的任何类都是不可访问的 - 这包括派生类。

另一方面,

Protected methods可以访问它们所在的类及其派生类。

您对受保护的使用是正确的。

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

答案 2 :(得分:3)

您可以构建覆盖挂钩。 Microsoft使用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.
  }
}

答案 3 :(得分:2)

我推荐以下内容:

尝试在抽象类中使用protected作为成员变量声明。然后使用public作为抽象方法。

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

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