24

I tried to use method overloading in some dart code and quickly learned that overloading is not offered in dart.

My questions are: why is it not offered, and what is the recommended alternative? Is there a standard naming convention since methods that do the same thing but with different inputs must have different names?

Is it standard to use named parameters and then check that the caller has supplied enough information to complete the calculation?

Say I have a method that returns how much money someone makes in a year, called yearlyIncome.

In Java, I would create a method like this

double yearlyIncome(double hourlyRate, double hoursWorkedPerYear)

And maybe another method like this

double yearlyIncome(double monthlyRate, int monthsWorkedPerYear)

and so on. They're all used to calculate the same thing, but with different inputs. What's the best, standardized way to do this in dart?

Thanks so much in advance.

loganrussell48
  • 1,656
  • 3
  • 15
  • 23

2 Answers2

29

Function overloading is not supported in Dart at all. Function overloading requires static types. Dart at its core is a dynamically typed language.

You can either use different names for the methods or optional named or unnamed parameters

// optional unnamed
void foo(int a, [String b]);

foo(5);
foo(5, 'bar');

// optional named
void foo(int a, {String b});

foo(5);
foo(5, b :'bar');

Optional parameters can also have default values. Optional named and unnamed parameters can not be used together (only one or the other for a single function) In the case of a constructor you can use named constructors as an alternative

barbecu
  • 684
  • 10
  • 28
  • Let's say I have a method to find the perimeter of a shape - `perimeter`. In a language that allows overloading, I could have a list of points that are the vertices of the shape as a parameter, `double perimeter(List vertices)`, or a list of side lengths `double perimeter(List sideLengths)`. In Dart, would you say I should accomplish this by adding a `Perimeter` class and using named constructors? `Perimeter.fromSideLength(listOfLengths)` or `Perimeter.fromVertices(listOfVertices)` seem a little overkill for something that ideally just returns a number – loganrussell48 Jun 28 '20 at 20:30
  • No, in this case if you insist on using the same method then you would have two optional named parameters and then check if one is null, If you already know what type you are passing in to the function though, then just create two functions with different names. – barbecu Jun 28 '20 at 20:39
7

Dart did not support overloading originally because it was a much more dynamic language where the declared types did not have any semantic effect. That made it impossible to use static type based overload resolution.

Dart has since changed to be more statically type, and there is nothing fundamentally preventing Dart from adding overloading today, except that it would be a huge work and a huge change to the language. Or so I'd assume, because there isn't any obvious design that isn't either highly complicated or hugely breaking.

What you do instead in Dart is to use optional parameters. A method like:

String toString([int radix]);

effectively have two signatures: String Function() and String Function(int). It can act at both signatures. There are definite limits to how far you can go with just optional parameters, because they still need to have exactly one type each, but that is the alternative that Dart currently provides. (Or use different names, but that's not overloading, you can do that in languages with overloading too).

Optional parameters is also one of the complications if we wanted to add overloading to the Dart language - would existing functions with optional parameters would count as multiple overloadings? If you declare a class like:

abstract class WithOverloading {
  String toString();
  String toString(int radix);
}

is that then the same signature as:

abstract class WithoutOverloading {
  String toString([int radix]);
}

Probably not because you can tear off the latter and get one function with an optional parameter, and you might not be able to tear off both functions from the former and combine them into one function. Or maybe you can, that's why it's not a trivial design question how to include overloading into the existing Dart language.

lrn
  • 64,680
  • 7
  • 105
  • 121