Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Optional Parameters in Abstract method? Is it possible?

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());
    }
}
like image 353
jordan Avatar asked Nov 05 '13 22:11

jordan


People also ask

Can we use optional as method parameter?

Java static code analysis: "Optional" should not be used for parameters.

Can a method have 2 optional parameters?

If you want to define multiple optional parameters, then the method declaration must be as shown below. The defined GetDetails() method can be accessed as shown below. GetDetails(1); GetDetails(1, "Rohini");

Can we pass optional parameters in Java?

Introduction to optional parameters in Java Unlike some languages such as Kotlin and Python, Java doesn't provide built-in support for optional parameter values. Callers of a method must supply all of the variables defined in the method declaration.

Can we pass parameter in abstract method in Java?

Core Java bootcamp program with Hands on practiceYes, we can define a parameterized constructor in an abstract class.


2 Answers

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());
    }
}
like image 182
competent_tech Avatar answered Nov 14 '22 22:11

competent_tech


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
    }
}
like image 34
David L Avatar answered Nov 14 '22 23:11

David L