I need to create overloads for functions on an existing interface without affecting any components that currently implement or make use of the interface (ideally).
I figure I have a couple of options:
Simplified Original interface:
public interface IServerComponent
{
bool Add(int a, int b);
}
I can add the new overloaded functions to the interface and force every class that implements the interface to implement the new functions.
public interface IServerComponent
{
bool Add(int a, int b);
bool Add(int a, int b, int c);
}
Or I can create a new interface that implements the original interface. Then other classes that make use of the original won't need to change and any new classes can implement the new interface...
public interface IServerComponent2 : IServerComponent
{
bool Add(int a, int b, int c);
}
What is the best practice is this situation? Are there any other options available?
Thanks
Interfaces define the specifications of entities and they can be implemented by functions or classes.
Do not add the method to the interface. If the method is relevant only for that one implementation, only add it to that one. The point of the interface is to abstract the common elements of every factory, so a method specific to a single factory should not be in the general factory interface.
Right-click the name of the interface. On the shortcut menu, choose Add > Add Method. In the Add Method wizard dialog box, provide the information to create the method as described in the next section. Select OK to add the method.
In addition to declaring default methods in interfaces, Java 8 also allows us to define and implement static methods in interfaces.
If the new methods can be expressed in terms of the old methods, you can use extension methods:
// Original interface
public interface IServerComponent
{
bool Add(int a, int b, int c);
}
// New overload
public static class MyServerMethods
{
public static bool Add(this IServerComponent component, int a, int b)
{
return component.Add(a, b, 0);
}
}
If the methods can't be expressed like that (i.e., they really need to be implemented by the components themselves), then I'd recommend defining a new interface. This approach has maximum backwards compatibility.
If your IServerComponent interface hasn't shipped yet or is an internal interface that is only implemented by your own classes, and the new interface members make sense for all existing classes implementing the interface, change the existing interface.
Otherwise, create an IServerComponent2 interface that extends IServerComponent. IIRC this is what the Framework Design Guidelines recommend. An example of this can be found in the .NET Framework in form of the X509Certificate2 class.
However, if the new members can be implemented in terms of the original members, you could also use extension methods:
public interface IServerComponent
{
bool Add(int a, int b);
}
public static class ServerComponentExtensions
{
public static bool Add(this IServerComponent isc, int a, int b, int c)
{
return isc.Add(a, b) && isc.Add(b, c) && isc.Add(c, a);
}
}
I realize your example is contrived but I want to give you a contrived answer that is different from what you are expressing so that maybe you can think about it in a different way. Instead of having your interface method operate on something concrete it might make sense to it instead work on something abstract.
For example
public interface IAddableThings
{
int a;
int b;
}
public interface IOtherAddableThings : IAddableThings
{
int a;
int b;
}
public interface IServerComponent
{
bool Add(IAddableThings things);
}
If this really is an Add then I think this makes a lot more sense, but if it is really more like Calculate(), you would then want to move some or all of that methods operation down to the IAddableThings objects.
public interface IAddableThings
{
int a;
int b;
bool CalculateMe();
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With