7

I have a abstract base class.

I have 2 derived classes from this base class.

Is there anyway that one of my classes can ignore the string parameter in the abstract overide usage? Or do I have to just send in a blank one and ignore it? (making readability drop slightly)

Can I have one function that has some sort of optional parameter so that both of the following derived classes would compile?

PS - The following code is riddled with in-compilable code for the example of what I would like to do

PS PS - Yes i have compiled the following code already - see above comment for outcome

public abstract class MyBaseClass
{                                            //optional string?
    public abstract void FunctionCall(int i, string s = "");
}

public class MyDerivedClass : MyBaseClass
{
    public override void FunctionCall(int i)
    {
        MessageBox.Show(i.ToString());
    }
}

public class YourDerivedClass : MyBaseClass
{
    public override void FunctionCall(int i, string s)
    {
        MessageBox.Show(s + " " + i.ToString());
    }
}
jordan
  • 3,436
  • 11
  • 44
  • 75

3 Answers3

10

If you don't absolutely need FunctionCall to be abstract, you can declare two versions of it:

public abstract class MyBaseClass
{
    public virtual void FunctionCall(int i)
    {
        this.FunctionCall(i, "");
    }
    public virtual void FunctionCall(int i, string s)
    {

    }
}

public class MyDerivedClass : MyBaseClass
{
    public override void FunctionCall(int i)
    {
        MessageBox.Show(i.ToString());
    }
}

public class YourDerivedClass : MyBaseClass
{
    public override void FunctionCall(int i, string s)
    {
        MessageBox.Show(s + " " + i.ToString());
    }
}

Otherwise, if it must be abstract to ensure it is implemented, you could still add two versions, it just makes the inheritors more verbose:

public abstract class MyBaseClass
{
    public abstract void FunctionCall(int i);
    public abstract void FunctionCall(int i, string s);
}

public class MyDerivedClass : MyBaseClass
{
    public override void FunctionCall(int i, string s)
    {
        throw new NotImplementedException();
    }
    public override void FunctionCall(int i)
    {
        MessageBox.Show(i.ToString());
    }
}

public class YourDerivedClass : MyBaseClass
{
    public override void FunctionCall(int i)
    {
        throw new NotImplementedException();
    }
    public override void FunctionCall(int i, string s)
    {
        MessageBox.Show(s + " " + i.ToString());
    }
}
competent_tech
  • 44,465
  • 11
  • 90
  • 113
  • What are the drawbacks of making them virtual opposed to abstract? – jordan Nov 05 '13 at 23:01
  • 2
    You are welcome. The primary drawback to making them virtual is that they are no longer required to implemented by the inheritors. The impact of this on your application entirely depends on the functionality of those methods and whether the class will be consumed by external callers. My preferred approach, simply because of verbosity, is to implement them as virtual and throw a not implemented exception in the base class. With proper unit testing, this will have much the same effect as declaring them abstract. – competent_tech Nov 05 '13 at 23:04
3

It will throw a compile error: "Abstract Inherited member 'MyBaseClass.FunctionCall(int, string)' is not implemented".

So no, the short answer is you can't do this.

Instead, you would have to do method overloading and implement BOTH abstract methods.

public abstract class MyBaseClass
{    
    public abstract void FunctionCall(int i);                                        
    public abstract void FunctionCall(int i, string s = "");
}

public class MyDerivedClass : MyBaseClass
{
    public override void FunctionCall(int i, string s = "") { }

    public override void FunctionCall(int i)
    {
        MessageBox.Show(i.ToString());
    }
}

public class YourDerivedClass : MyBaseClass
{
    public override void FunctionCall(int i, string s)
    {
        MessageBox.Show(s + " " + i.ToString());
    }

    public override void FunctionCall(int i) {}
}

However this seems quite messy. Perhaps the best option is to always use the optional parameter and simply not pass in a value if it is not needed or handle it as you already seem to be doing.

public class MyDerivedClass : MyBaseClass
{
    public override void FunctionCall(int i, string s = "") 
    {
        if (!string.IsNullOrEmpty(s))
            MessageBox.Show(i.ToString());
        else
           // handle other path here
    }
}
David L
  • 32,885
  • 8
  • 62
  • 93
3

One possible way is to use extension methods to add missing overrides (which also works with interfaces)

static class MyBaseClassExtensions
{
       public void FunctionCall(MyBaseClass this item, int i)
       {
            item.FunctionCall(i, null);
       }
}
Alexei Levenkov
  • 98,904
  • 14
  • 127
  • 179