Often
you’ll
want to
have more than one function with the same name. The most common
example of this is to have more than one constructor. In the examples
shown so far, the constructor has taken a single parameter: a
DateTime
object. It would be convenient to be able
to set new Time
objects to an arbitrary time by
passing in year, month, date, hour, minute, and second values. It
would be even more convenient if some clients could use one
constructor, and other clients could use the other constructor.
Function overloading provides for exactly these contingencies.
The signature of a method is defined by its name and its parameter list. Two methods differ in their signatures if they have different names or different parameter lists. Parameter lists can differ by having different numbers or types of parameters. For example, in the following code the first method differs from the second in the number of parameters, and the second differs from the third in the types of parameters:
void myMethod(int p1); void myMethod(int p1, int p2); void myMethod(int p1, string s1);
A class can have any number of methods, as long as each one’s signature differs from that of all the others.
Example 4-9 illustrates our Time
class with two constructors, one which takes a
DateTime
object, and the other which takes six
integers.
Example 4-9. Overloading the constructor
public class Time { // public accessor methods public void DisplayCurrentTime( ) { System.Console.WriteLine("{0}/{1}/{2} {3}:{4}:{5}", Month, Date, Year, Hour, Minute, Second); } // constructors public Time(System.DateTime dt) { Year = dt.Year; Month = dt.Month; Date = dt.Day; Hour = dt.Hour; Minute = dt.Minute; Second = dt.Second; }public Time(int Year, int Month, int Date, int Hour, int Minute, int Second)
{ this.Year = Year; this.Month = Month; this.Date = Date; this.Hour = Hour; this.Minute = Minute; this.Second = Second; } // private member variables private int Year; private int Month; private int Date; private int Hour; private int Minute; private int Second; } public class Tester { static void Main( ) { System.DateTime currentTime = System.DateTime.Now; Time t = new Time(currentTime); t.DisplayCurrentTime( );Time t2 = new Time(2000,11,18,11,03,30);
t2.DisplayCurrentTime( );
} }
As you can see, the Time
class in Example 4-9 has two constructors. If a function’s
signature consisted only of the function name, the compiler would not
know which constructors to call when constructing
t1
and t2
. However, because the
signature includes the function argument types, the compiler is able
to match the constructor call for t1
with the
constructor whose signature requires a DateTime
object. Likewise, the compiler is able to associate the
t2
constructor call with the constructor method
whose signature specifies six integer arguments.
When you overload a method, you must change the signature (i.e., the name, number, or type of the parameters). You are free, as well, to change the return type, but this is optional. Changing only the return type does not overload the method, and creating two methods with the same signature but differing return types will generate a compile error.
This is illustrated in Example 4-10:
Example 4-10. Varying the return type on overloaded methods
public class Tester { private int Triple(int val) { return 3 * val; } private long Triple (long val) { return 3 * val; } public void Test( ) { int x = 5; int y = Triple(x); System.Console.WriteLine("x: {0} y: {1}", x, y); long lx = 10; long ly = Triple(lx); System.Console.WriteLine("lx: {0} ly: {1}", lx, ly); } static void Main( ) { Tester t = new Tester( ); t.Test( ); } }
In this example, the Tester
class overloads the
Triple( )
method, one to take an integer, the
other to take a long. The return type for the two Triple( )
methods varies. Although this is not required, it is very
convenient in
this
case.
18.227.190.211