Before I start the article, I admit I used the word "Function" a little loosely in the title. Functions are available in C++, but in C# and Java it would be more appropriate to call them methods of a class because of the Object Oriented approach followed by these languages.
There are a lot of situations where we write modules such that other developers have the flexibility to fine-tune them to meet their requirements. Assume we are writing a module (function/method) wherein a function/method will be called in the middle of its execution but we don’t know the implementation of this function/method nor its actual name. Wouldn't it nice if we could just leave the implementation of the function/method to the developer who will be using the module?
This is exactly what I target in this blog-post. The article will give a quick overview of how to pass a function (actually a reference to a function) to another function in C++; how to create and use delegates in C#; and finally how to simulate a similar effect in Java which has neither pointers nor delegates.
To help the readers understand the concept better, I will be taking a simple example here. In the example, there is an addition module which takes three arguments - two integers and a function/method which is the display routine. It's not a real-world example as I could have just returned the sum back.
An apt real-world example for this approach would a customized sort routine which takes a function/method which can be used as a comparator for the sort. I will leave it to the users to think of more complex situations where such an approach will be beneficial.
Function Pointers in C++
A Function Pointer is a pointer in C/C++ which points to a function. When dereferenced, a function pointer will result in the execution of the function it points to. A function pointer is defined as -
An important point that is to be noticed here is that the signature of the function to which the pointer can point to has to be declared in the declaration of the pointer. Once that is done, it can be assigned to any function which follows that signature.
Here is an example C++ program which uses function pointers -
Function pointers play a very important in Callback layered architectures. For example, function pointers can be used to register a function with an event handler.
Delegates in C#
A delegate is a type that references to a method. When a method is assigned to a delegate, the delegate behaves exactly like the method. A delegate in C# is defined as -
access_modfier delegate return_type delegate_name(argument_list)
Similar to Function Pointers in C/C++, the method signature has to be specified in the definition of the delegate. But unlike function pointers, delegates are type safe. This is because since Function Pointers are basically pointers, even an improper assignment will not raise any error until it’s too late. On the other hand delegates are associated with the signature specified and any wrong assignment will lead to a compilation error.
Another important feature of delegates is that delegates can be chained together. That is, multiple functions can be executed when the delegate is called. This is done through + and - operations on delegates. Here is how the syntax looks -
reference_name = method1_name;
reference_name += method2_name;
Now when reference_name is called, both method1_name and method2_name are executed one after another.
Delegates also allow methods to be passed to other methods using lambda expressions, which can be written in the method call itself. Go through the following example which shows how to use delegates for method passing and how lambda expressions are useful -
Delegates are very useful in event handling, for defining callback methods like a customized sort, etc.
Simulation Using Interfaces in Java
Ok, now coming to the fun part. How can I get the same effect in Java which has neither Function Pointers nor Delegates?
The approach which have discussed above can be simulated in Java using single method Interfaces. The single method interface can be implemented and the class can become an argument of the method. The concrete class passed to the method is used to call the one and only method of the interface.
However, there are three major drawbacks in this -
- Every developer using the method is forced to create a class implementing the interface
- The name of the function is fixed, the implementation will change but not its name
- We are not passing the method anymore but instead passing an object which has the required method
Similar to C#, the interface implementation can be done in-line to the method call using anonymous classes.
Here is a Java program which achieves the same result as the above two examples -
As we know, C# was heavily influenced by Java. So, almost everything that we can do in Java can be done in C#. The interface technique discussed for Java can also be applied in C#, but I guess it’s more easy to use Delegates for such a requirement than creating Interfaces.