Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to Implement a Base Class with a Method and yet force the Derived Class to Override it?

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.

like image 707
Tipx Avatar asked Aug 25 '09 02:08

Tipx


2 Answers

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.

like image 139
Nader Shirazie Avatar answered Sep 27 '22 21:09

Nader Shirazie


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
  }
}
like image 24
Tipx Avatar answered Sep 27 '22 21:09

Tipx