Today, I’m going to try my hand at the ELI5 trend by explaining a common programming concept: method overloading. Having written this part last, I’m realizing that it’s really hard to simplify programming concepts, but I tried my best. In the future, it might be fun to do a “5 levels” style of article where I try to cover a concept for folks at different levels of expertise. At any rate, let’s get into it!
Table of Contents
Defining Method Overloading
In programming, we tend to organize our code into bite sized chunks called methods (or if you prefer: functions, procedures, routines, etc.). A method is really just a black box: input comes in (i.e., arguments) and output goes out (i.e., a return value). These inputs and outputs are typically bound to some type (e.g., integers, strings, etc.), so we always know what we’re dealing with.
While these black boxes are useful, sometimes we find that they’re a bit too restrictive. For example, maybe we have a method that performs an action like throwing an object. This method is currently limited to throwing balls, but maybe we want the method to be able to handle other types of objects. That’s when method overloading comes in!
Method overloading allows us to have multiple methods with the same name (e.g., throw) but different inputs. For instance, we might have one method that throws balls and another method that throws boomerangs. Both methods are called “throw”, but their behavior will be different. This becomes convenient for us in the future because we can intuitively use the name “throw” in our code without putting together dozens of “throw” methods (e.g., throwBall, throwBoomerang, throwRock, etc.).
Method Overloading in Practice
Now, method overloading in practice really depends on the language you are using. Sticking with our throwing example, we can very easily replicate the description above using Java:
public static boolean throw(Ball b, Teammate t) { // throw the ball to the teammate and tell us if it was successful } public static boolean throw(Rock r, Target t) { // throw the rock to the target and tell us if it was successful } public static boolean throw(Boomerang b) { // throw the boomerang and tell us if it returned successfully }
Notice how we have three “throw” methods with wildly different parameters. One is for throwing a ball to a teammate, another is for throwing a rock at a target, and the last one is for throwing a boomerang to ourselves. Yet, all three methods have the same name and return value.
Not all languages provide such easy or obvious ways to accomplish overloading. In Python, you can’t actually have multiple methods with the same name. However, you can have optional parameters:
def throw(ball=None, teammate=None, rock=None, target=None, boomerang=None) -> bool: pass
As you can probably imagine, this is a bit of a nightmare to manage since you basically need to test for the right combinations yourself:
def throw(ball=None, teammate=None, rock=None, target=None, boomerang=None) -> bool: if ball and teammate: pass elif rock and target: pass elif boomerang: pass
That said, you can definitely overload methods in this way. Alternatively, I suppose you could group parameter sets into tuples:
def throw(ball_and_teammate=None, rock_and_target=None, boomerang=None) -> bool: if ball_and_teammate: pass elif rock_and_target: pass elif boomerang: pass
Though, I’m not sure this really solves any issues. After all, why not just accept a tuple as input? Or use keyword arguments?
def throw(**kwargs) -> bool: if kwargs.get("ball") and kwargs.get("teammate"): pass elif kwargs.get("rock") and kwargs.get("target"): pass elif kwargs.get("boomerang"): pass
Not to mention that all of these solutions run into the issue of “what if a user provides a ball, teammate, rock, and target?” Regardless, these are ways you might accomplish method overloading in Python.
Common Misconceptions
Method overloading is a programming language feature that likely doesn’t get used very often. While I use optional parameters in Python, I tend to only use them to enhance a method, not give it alternative parameter sets. As for Java and languages like it, I’ve probably used overloading once or twice. In both cases, what I’ve used far more often is method overriding.
Method overriding is often confused with overloading because of their close names. And in practice, the two terms are also quite similar. In fact, they both apply to working with methods that have the same name. The difference is that method overriding is used to describe the creation of a method that is meant to change the behavior of an existing method in the hierarchy.
For example, using the same throwing method, we can imagine that humans in general are able to throw objects. However, we might want a different “throw” method for each subcategory of human. In other words, a professional baseball player might through a ball differently than a chess player. Therefore, humans might have some generic “throw” method while baseball players have a more specialized “throw” method. Here’s what that might look like in code:
public class Human { public boolean throw(Baseball b, Human h) { return h.isInRange(); } } public class BaseballPlayer extends Human { @override public boolean throw(Baseball b, Human h) { return super.throw(b, h) && !this.playIsDead(); } }
Hopefully, with this example, it’s more clear how overriding is different. When BaseballPlayer inherits from Human, it gets the default “throw” method that will just throw the ball if the target is in range. Since the context of a BaseballPlayer is a bit different, we’ve taken the same condition and added an extra one (i.e., only throw the ball if the play is not dead).
To summarize, method overloading generally refers to a set of methods that share the same name and return type but different parameters (though other languages may support different return types). Meanwhile, method overriding refers to changing the behavior of a method higher up in the class hierarchy. In my experience, overriding happens a lot more often as many objects exist in some form of hierarchy (e.g., toString() and equals() in Java).
With all that said, I think that’s all I want to cover today. If you liked this article and want to see more like it, check out any of these:
- Beware of Division by Zero in Java
- The Difference Between Private and Public in Java
- Dump Java: Life Is Just Better in Python
Otherwise, take care!
Recent Posts
While creating some of the other early articles in this series, I had a realization: something even more fundamental than loops and if statements is the condition. As a result, I figured we could...
Today, we're expanding our concept map with the concept of loops in Python! Unless you're a complete beginner, you probably know a thing or two about loops, but maybe I can teach you something new.