如何使用方法实现基类并强制派生类覆盖它?

发布于 2024-08-02 13:54:57 字数 903 浏览 6 评论 0原文

有这样的事情:

public abstract class AAA
{
  protected abstract virtual string ToString()    // Error
  {
    // Base Stuff
  }
}

public abstract class BBB : AAA
{
  public override string ToString()
  {
    // Use base.ToString();
    // More Stuff
  }
}

我读了另一篇文章(虚拟类中的抽象方法)女巫很像我的问题,但有一点区别。我希望 AAA.ToString() 有一个基本行为强制派生类覆盖它。

我知道我可以做这样的事情(向下滚动),但我一直在寻找合适的方法。

public abstract class AAA
{
  public abstract string ToString();
  protected string ToString2()
  {
    // Base Stuff
  }
}

public class BBB : AAA
{
  public override string ToString()
  {
    // Use base.ToString2();
    // More Stuff
  }
}

我也可以制作一个 IAAA 接口并构建我的 BBB 类,

public class BBB : AAA, IAAA { ... }

但对我来说看起来不太合适。

Having something like this this :

public abstract class AAA
{
  protected abstract virtual string ToString()    // Error
  {
    // Base Stuff
  }
}

public abstract class BBB : AAA
{
  public override string ToString()
  {
    // Use base.ToString();
    // More Stuff
  }
}

I read another post (abstract method in a virtual class) witch was pretty like my question, but there is a little difference. I'd like AAA.ToString() to have a base behavior and force the derived class to override it.

I know I could do something like this (scroll down) but I was looking for a proper way.

public abstract class AAA
{
  public abstract string ToString();
  protected string ToString2()
  {
    // Base Stuff
  }
}

public class BBB : AAA
{
  public override string ToString()
  {
    // Use base.ToString2();
    // More Stuff
  }
}

I could also probably make a IAAA interface and build my BBB class like

public class BBB : AAA, IAAA { ... }

but don't look right to me.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

冧九 2024-08-09 13:54:57

您的方法本质上是正确的方法...

编辑:

您的“规范”是:

  1. 默认行为
  2. 需要覆盖

现在,因为您似乎希望始终执行“默认行为”,所以您

public string ToString()
{
    // placeholder for some default behaviour

    string result = doToString();

    // placeholder for some more default behaviour

    return result;
}

protected abstract string doToString();

只需要这如果您知道基类一般在做什么,并且想要在派生类中提供 doToString() 的实现,则可以使用。这称为模板方法设计模式。

但是,如果您正在寻找一种方法来要求派生类的实现者在其 ToString()base.ToString() code>,那么就没有办法做到这一点。通过允许重写,您可以让派生类控制其实现。

您可以记录您的建议,以始终调用 base.ToString(),但仅此而已。

使用接口定义类的公共契约。与模板方法模式相比,这不会给您带来任何额外的好处,因为您仍然需要从基类派生以获得“默认”实现。

您是否有关于您试图在基类中提供的“默认行为”的详细信息?也许这将有助于找到更好的解决方案。查看引用的问题,这本质上是相同的方法。

Your approach is essentially the proper way...

Edit:

Your "specification" is:

  1. Default behaviour
  2. Required override

Now, since you appear to want the "default behaviour" to always be executed, you need

public string ToString()
{
    // placeholder for some default behaviour

    string result = doToString();

    // placeholder for some more default behaviour

    return result;
}

protected abstract string doToString();

This only works if you know what the base class is doing in general, and want to provide the implementation for doToString() in the derived class. This is known as the Template Method design pattern.

However, if you are looking for a way to require the implementer of a derived class to call base.ToString() in its implementation of ToString(), then there's no way to do this. By allowing an override, you give the derived class control over its implementation.

You can document your recommendation to always call base.ToString(), but that's about it.

Using an interface defines the public contract for your class. This doesn't give you any additional benefit over the Template Method pattern, since you still need to derive from a base class to obtain the "default" implementation.

Do you have any details about what you are trying to provide in your base class as the "default behaviour"? Maybe that will help come to a better solution. Looking at the referenced question, this is essentially the same approach.

念三年u 2024-08-09 13:54:57

我刚刚知道该怎么做才能得到我想要的行为:

public abstract class AAA
{
  protected abstract string ToStringSpecific();
  protected string ToString()
  {
    // Base Stuff
    ...
    // Use this.ToStringSpecific();
  }
}

public class BBB : AAA
{
  protected override string ToStringSpecific()
  {
    // Specific Stuff
  }
}

I just found out what to do to get exactly the behavior I wanted :

public abstract class AAA
{
  protected abstract string ToStringSpecific();
  protected string ToString()
  {
    // Base Stuff
    ...
    // Use this.ToStringSpecific();
  }
}

public class BBB : AAA
{
  protected override string ToStringSpecific()
  {
    // Specific Stuff
  }
}
沫雨熙 2024-08-09 13:54:57

不,不可能将当前的虚拟函数变成抽象函数。正如您所建议的,强制执行此操作的唯一方法是创建另一个抽象函数。这可以说是一种更合适的方法(我同意这一点)。

No, it isn't possible to turn a currently virtual function into an abstract function. The only way of enforcing this would be to create another function that's abstract, as you suggested. This is arguably a more appropriate approach (and I would agree with that).

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文