11

Suppose I am working on an existing, reasonably large system. I have an object, myObject of class MyClass (for the example's sake, suppose I'm working in Java). myObject is a composition containing a Collection, say, a List and other objects which (I think) are irrelevant. It contains delegate methods which just serve to call upon the methods of the List it is composed of, in order to ensure the List it has is not exposed (sorry if I've got my terminology wrong).

Let's say that this List is a List<String> but, for some reason, the main access method is a mask method for class SomeOtherClass. If I wanted to insert a new value pair into my List, then I'd have an object of SomeOtherClass called someObject. I'd call myObject.insert(someObject) and inside the insert method there would be some magic that would retrieve a String to put into the List<String>.

Supposing now that I've only got a String value, and no SomeOtherClass object to insert. Assuming I can't modify the insert method because it would break everything in this system. Then should I overload the insert method? Or should I create a new object of SomeOtherClass every time I want to call insert?

I guess if I did overload it, it would look something like this...

public void insert(String s) {
    ...
}

public void insert(SomeOtherObject obj) {
    this.insert(obj.magicStringMethod());
}

(This example is a contrived puzzle based upon a similar (slightly more complex) situation regarding overloading that I encountered yesterday. I'll expand it if there's anything that was unclear)

Would this be an appropriate place to overload a method? If not, when should I overload a method?

3
  • Assuming Java, have you looked into using Generics to solve this problem? I guess what I'm really asking is what does the String really represent? If it's actually really a representation of an actual domain object then there's another potential way to solve this issue Commented Feb 16, 2012 at 2:16
  • @MartijnVerburg I haven't, at this stage. Since I'm only an intern, I'm still a little unfamiliar with things like design patterns and I don't have good design practice habits yet. In answer to your second question, it is a representation of an actual domain object. magicStringMethod() in my example would, in my case, get a String representation of SomeOtherObject which was a domain object.
    – blahman
    Commented Feb 16, 2012 at 2:28
  • I suggest you stayed away from overloading when you can. It does cause confusion sometimes. Its best to be certain about the called method at design time. See this: programmers.stackexchange.com/questions/132369/…
    – NoChance
    Commented Feb 16, 2012 at 9:23

3 Answers 3

9

You overload when you wish to support different types:

public overload void MyMethod(int value)
{ 
}

public overload void MyMethod(bool value)
{
}

public overload void MyMethod(string value)
{
}

or to support a progressive interface using different parameter lists:

public overload void MyOtherMethod()
{
    this.MyOtherMethod(DefaultValue);
}

public overload void MyOtherMethod(int value)
{
    this.MyOtherMethod(value, DefaultOtherValue);
}

public overload void MyOtherMethod(int value, bool otherValue)
{
    ...
}

You might even get a little crazy and support both different types AND a progressive interface, but you should bear in mind that you need to avoid creating variations in behaviour between overloaded methods. Each overloaded method should be functionally the same as the others in an overloaded group, otherwise it will be unclear as to how, when or why behaviour is being varied. If you want two functions to do something completely different, then you should name them accordingly.

7

I would say that overloading is appropriate when both of the methods are semantically equivalent. To steal from dukeofgaming's examples:

These are overloaded appropriately:

public int sum(int a, int b){
    return a+b;
}

public double sum(double a, double b){
    return a+b;
}

These are not:

public int sum(int a, int b){
    return a+b;
}

public double sum(double a, double b){
    return a-b;
}

That is an extreme example (if you didn't catch it, the last method actually subtracts instead of adds), but the idea is that if you have multiple methods in a class with the same name they should behave consistently.

In your example, from the information given they appear to be equivalent (since one calls the other) and I would think it reasonable to overload them. It can't hurt to ask someone more senior in your team if you are unsure about whether the method should be added but if you did add it I would use the same name (i.e. I would overload it).

1
  • 1
    Thanks for the answer. I did ask someone more senior, but since the code is in a somewhat interesting state their solution was one I wasn't sure about, but nevertheless implemented (it was not the overloading).
    – blahman
    Commented Feb 16, 2012 at 4:44
5

Essentially to have the parameters of the method dictate how the method will behave.

A quick example would be:

class Calc{
    //...
    public int sum(int a, int b){
        return a+b;
    }
    public double sum(double a, double b){
        return a+b;
    }
    //...
}

If you pass the method sum(a,b) a couple of integers it knows that it should call the first implementation, since the method call coincides with the method signature (i.e. double sum(double,double) will not work if you give the sum method two integers).

The signature of the call must match the available implementations, so trying to call sum(string, string) will not work unless you have this:

class Calc{
    //...
    public int sum(int a, int b){
        return a+b;
    }
    public double sum(double a, double b){
        return a+b;
    }
    public string sum(String a, String b){
        return "" + (Double.parseDouble(a) + Double.parseDouble(b));
    }
    //...
}

tl;dr: To have the class handle the correct method according to whatever parameters you give a method with the same name.

When inheriting, it is called overriding

A good example of this other scenario is when you want to alter the default behavior of a class by inheriting it, and particularly when you have something similar to the template method pattern, where you have each step of some algorithm implemented in a method.

Imagine that you have class Robot and a method called fireAtTarget(Target target)... which calls fireWeaponA(target); fireWeaponB(target); fireWeaponC(target); one after each other. You also want to have a collection called robot_army to which you can only add objects of the class Robot. Robot fires machine guns by default in its fireWeaponX() methods.

Then you want to have class LazorRobot and class MissileRobot, do you implement Robot all over again?, no, just have LazorRobot and MissileRobot inherit Robot, and overload each fireWeaponX() method to use lazorz or missiles and you will have the same behavior with different weapons, without having to reimplement the rest of the methods.

tl;dr: To have the method's behavior depend on the class without breaking the interface (robot_army only accepts Robot, but accepts by extension any classes that inherit Robot).

5
  • Your first example is an override. When you maintain a method's interface yet change the behaviour in a descendant. The implication is that you do not intend to offer an alternative method. Your second example however is correctly overloading. If your intention is to highlight when to override vs when to overload, you may wish to make this clearer in your answer, otherwise the whole when inheriting section is probably not needed. :)
    – S.Robins
    Commented Feb 16, 2012 at 3:52
  • Derp, caffeine did get me this time =P, left the second part as the first and the first as the second for general interest. Thanks for the correction. Commented Feb 16, 2012 at 3:55
  • If I understand your answer correctly, I should be overloading only when looking at the parameters will allow me to infer the differences in behaviour between, say, sum(String, String) and sum(int, int)?
    – blahman
    Commented Feb 16, 2012 at 4:23
  • @blahman you should overload when you wish to use different types, a mixture of types, or even to add additional parameters. Overloading provides a way to create methods with default parameters where the param=value default syntax isn't supported. See my answer to see what I mean.
    – S.Robins
    Commented Feb 16, 2012 at 10:38
  • 1
    @blahman BTW and on another subject, when you have too many parameters and some of them are optional sometimes it is better to just send a single object or data structure that has all the default values, so you change the attributes of such object or data structure. That way you don't need to make 20 versions of the same method just to add a single parameter each time. Commented Feb 16, 2012 at 15:07

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.