17

假设我开设了一个主要课程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

4 回答 4

37

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

于 2012-08-12T21:20:31.393 回答
13

除了它们所在的类之外,任何类都无法访问私有方法——这包括派生类。

另一方面,受保护的方法可以被它们所在的类和它们的派生类访问。

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

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

于 2012-08-12T21:20:29.727 回答
3

您可以构建覆盖挂钩。Microsoft 使用FrameworkElement.ArrangeCore(...)(which uses ArrangeOverride) 和FrameworkElement.MeasureCore(...)(which uses 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.
  }
}
于 2012-08-12T22:10:04.937 回答
2

我推荐以下内容:

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

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

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

于 2012-08-13T00:40:13.417 回答