What is the basic concept of overloading a method - java

In overloading when we overload a method why we cant make a new method which works same as overloaded method because we have to write the same number of line of code Such as in my example...why i cant make a new method b() which multiply two numbers.
public class que {
public void a(int a)
{
System.out.println(a);
}
public void a(int b,int c) {
System.out.println(b*c);
}
public static void main(String[] args) {
que queObject = new que();
queObject.a(5);
queObject.a(3,4);
}
}

You can make all your methods have different names. The point is you don't have to. This reduces the number of names a developer using the API needs to learn.
e.g. in the PrintWriter you have lots of methods called print and println which conceptually all do the same thing. They could have been given different names, but then you would need to know which method you wanted to call,
At runtime, each method signature is unique as it includes the return type and the non generic argument types form. i.e. in byte code the names are made unique for you.
In Java, a method cannot be distinguished/overloaded by it's return type, though in Java 6 there was a bug which allowed overloading on methods with different return types.

Nobody says you can't do this. It just isn't method overloading. That's defined as two or more methods of the same name, but with different (parameter) signatures.

method name signifies what a method does. so if you have 2 methods having same name but expects different arguments. its beneficial for the understanding of code and better design to have the same name.
so if you add another method
public void a(int b,int c,int d) {
System.out.println(b*c*d);
}
you basically doing the same behaviour i.e. multiplication but with more arguments. so overriding is better for understanding and good coding principles.

Consider This
public void eat(Orange o) {
// eat Orange
}
public void eat(Mango m) {
// eat Mango
}
You want different implementation on the basis of what you pass as a parameter but want to keep method name same.
For More Info --> Polymorphism vs Overriding vs Overloading

Here's my explanation:
public class Calculator {
// used for integer numbers
public int sum(int a, int b) {
return a + b;
}
// used for double numbers
public double sum(double a, double b) {
return a + b;
}
}
In this case you don't care if you use sum method with int or double - sum method is overloaded, so it will take both int and doubles. It's much easier than using sumInts() and sumDoubles() separately.

Method overloading is when, in a class, there are more than one method with same name but different arguments although it can have different return types (different return types is in itself is not a distinguishing feature and if only that is changed will result in a compile error).
For a complete discussion, see: http://beginnersbook.com/2013/03/polymorphism-in-java/
Why do we need it?
An example will be enlightening: Lets take the ubiquitous StringBuilder class and its append methods. They are a prime example of overloading. A specific instance of method overloading is constructor overloading as well. See the StringBuilder again: http://docs.oracle.com/javase/7/docs/api/java/lang/StringBuilder.html.
As another example suitable to your case: we can have an appendBoolean(boolean b) and a appendString(String b) and a appendChar(char c) in the StringBuilder class as well. It is a matter of clarity and choice to either have that or just have a set of overloaded append methods. To me - since the operation is to append but we are appending different instance types - having an overloaded append makes sense and provides clarity and is concise. On the other hand, you have no such choice for overloaded constructors: they need to have the same name as the class - that is by convention and by design :-)

Related

Overloading or a normal method [duplicate]

This question already has answers here:
Is it possible to have different return types for a overloaded method?
(13 answers)
The relationship of overload and method return type in Java?
(4 answers)
Closed 6 years ago.
I am gonna put this question to have a clear idea about overloading Concept in java . As per my understanding while method resolution in overloading compiler will look for method signature that is it should have same method name and different argument types . But what if the return type is different ??
class Test{
public void m1(int i) {
System.out.println(" int arg");
}
public int m1(String s) {
System.out.println("String-arg");
return (5+10);
}
public static void main (String[] args) throws java.lang.Exception
{
Test t = new Test();
t.m1(5);
int i = t.m1("ani");
System.out.println(i);
}}
the above program is running perfectly . my doubt here is , the method m1() is it overloaded ?? it has different return type . someone please make it clear. Thanks in advance
In Java methods are identified by name and arguments' classes and amount. The return type doesn't identify the method. For this reason the following code would be illegal:
public void m1(String i) {
System.out.println(" int arg");
}
public int m1(String s) {
System.out.println("String-arg");
return (5+10);
}
If two methods of a class (whether both declared in the same class, or both inherited by a class, or one declared and one inherited) have the same name but signatures that are not override-equivalent, then the method name is said to be overloaded. (...) When a method is invoked (§15.12), the number of actual arguments (and any explicit type arguments) and the compile-time types of the arguments are used, at compile time, to determine the signature of the method that will be invoked (§15.12.2). If the method that is to be invoked is an instance method, the actual method to be invoked will be determined at run time, using dynamic method lookup (§15.12.4)
Summarizing, two methods with the same name can return different types, however it's not being taken into account when deciding which method to call. JVM first decides which method to call and later checks if the return type of that method can be assigned to the certain variable.
Example (try to avoid such constructions):
public int pingPong(int i) {
return i;
}
public String pingPong(String s) {
return s;
}
public boolean pingPong(boolean b) {
return b;
}
if we follow the Oracle definition then yes, it is a overloaded method
here the info (emphasis mine)
The Java programming language supports overloading methods, and Java
can distinguish between methods with different method signatures. This
means that methods within a class can have the same name if they have
different parameter lists (there are some qualifications to this that
will be discussed in the lesson titled "Interfaces and Inheritance").
the fact that the method return a value or not is IRRELEVANT for the overloading definition...
another thing is here why can a method somethimes return a value and sometimes no...
this will drive crazy the people using the code, but that is another question...

Should I use Objects to avoid method overloading or method overloading is better?

I have two interface structures.
MyInterface1
public interface MyInterface1{
public Object SUM(Object O,Object P);
}
MyInterface2
public interface MyInterface2{
public int SUM(int O,int P);
public double SUM(int O,double P);
public double SUM(double O,double P);
public double SUM(double O,int P);
}
Which is a better design approach to implement the interface so that code efficiency is maintained?
The second approach (overloading) is much more preferred since it contains method signatures that are strongly typed.
Think about the following code.
public class InterfaceImpl implements MyInterface2{
public Object SUM(Object O,Object P){
//Really what can I do here without casting?
/* If I have to cast, I might as well define
types in the method signature, guaranteeing
the type of the arguments
*/
//Lets cast anyway
return (Integer) O + (Integer) P;
}
public static void main(String[] args) throws ParseException {
System.out.println(SUM(1,2)); //Excellent Returns 3
//Yikes, valid arguments but implementation does not handle these
System.out.println(SUM(true,false)); //Class cast exception
}
}
Conclusion
As more types are encountered that the method needs to handle, the implementation will be forced to perform type checking before doing the necessary casts. In theory type checking would need to occur for every class that extends Object, since the method signature only restrains arguments to the type. Since the arguments are objects there will be an infinite amount of types to check, rather impossible.
By using overloaded methods you express the intent of the method as well as restrict the set of allowable types. This makes writing the implementation of the method much easier and manageable, since arguments will be strongly typed.
As the other answers already mentioned, overloading is better.
But I would also add that you don't need 4 versions, only 2:
public interface MyInterface2 {
public int SUM(int O, int P);
public double SUM(double O, double P);
}
If you call SUM with an (int,double) or (double,int) the int will get upcasted to a double and the second of the methods is the one that will run.
For example, the code below compiles and prints "goodbye":
public class Test implements MyInterface2 {
public int SUM(int o, int p) {
System.err.println("hello");
return o + p;
}
public double SUM(double o, double p) {
System.err.println("goodbye");
return o + p;
}
public static void main(String[] arg) {
Test t = new Test();
t.SUM(1.0, 2);
}
}
In this case second option is good. But it varies from code to code. Example
interface InterfaceFrequencyCounter
{
int getCount(List list, String name);
}
interface AnotherInterfaceFrequencyCounter
{
int getCount(ArrayList arrayList, String name);
int getCount(LinkedList linkedList, String name);
int getCount(Vector vector, String name);
}
so now in above given case second option is not good practice. First one is good.
Overloading is better, as you don't want someone to call you method with a String or something.
What you can do, is using a common super class if you have one (Number in your case - if you wish to get Long and Float too).
For safe code method overloading better approach.
Overloading is better as described above.
If you run into a situation described by AmitG, you should use interfaces and not just the most generic object type. Anyways, your method almost always can work properly with only some subset of objects, not all of them. In that case you need to find a common interface and use it in a method signature, just like AmitG did in his example. The use of interface shows your intent to method cliens clearly, it's typesafe and removes the need to do casting inside the method.

Is this Overloading, methods with same name in different classes and different signature?

If I have the following code in Java:
class A {
public int add(int a , int b) {
return (a+b);
}
}
class B extends A {
public float add(float a , float b) {
return (a+b);
}
In this particular case the sub-class isn't exactly overriding the base class's add function as they have different signatures and the concept of overloading occurs only if they are in the same scope. So, is the function add(float , float) in the sub-class B treated as an entirely new function and the concept of overloading and overriding is not applicable to it? And does it use 'Static binding' or 'Dynamic Binding'?
Method add in class b is an overload of add in class a. Not an override. An override would just be a different implementation of the original add method.
In brief, yes. To override, you need to replicate the complete method signature, which includes the method name, parameters and return types. From the tutorial
An instance method in a subclass with the same signature (name, plus
the number and the type of its parameters) and return type as an
instance method in the superclass overrides the superclass's method.
You might want to consider the #Override annotation, which will trigger a compiler error if you don't successfully overrride a method.
In this particular instance, it perhaps looks like you don't need overriding so much as some solution including generics. So you could instantiate a class a<Integer> and a similar class a<Float>
In that case you are not overriding the method, since the signatures are different.
But there is overloading in class b, since you have two methods with the same name but different parameters (one if class a, and the other one in class b)
Hope it helps.
There can be a method that is not overridden but overloaded in the subclass. Here the subclass has two add() methods. The version which accepts int arguments(not overridden), and the overloaded method add() which accepts float arguments.
I think in this particular case neither overloading nor overriding occurs, because return type must be same in case overloading and overriding, so neither static binding nor dynamic binding happens in this case.
method overloading is not possible in case of different return type, because compiler can't figure that which method he need to call.
I know it's late answer but i think it's important question need to be answered for beginners.
One key point in overloading is it works in inheritance.
Next is either it's Static binding or Dynamic binding.
It is Static Binding So, why?
Static Binding
Static binding in Java occurs during Compile time.
private, final and static methods and variables uses static binding and bonded by compiler.
Static binding uses Type (class in Java) information for binding.
Dynamic Binding
Dynamic binding occurs during Runtime.
Dynamic methods bonded during runtime based upon runtime object.
Dynamic binding uses Object to resolve binding.
But the important part is here
Overloaded methods are bonded using static binding while overridden methods are bonded using dynamic binding at runtime.
Java compiler determines correct version of the overloaded method to be executed at compile time based upon the type of argument used to call the method and parameters of the overloaded methods of both these classes receive the values of arguments used in call and executes the overloaded method.
B a=new B();
a.add(4, 5);
a.add(4.0f, 5.0f);
So if you will create reference of type B then it will search for proper argument type
and for above code it will execute both methods.
A a=new B();
a.add(4, 5);
a.add(4.0f, 5.0f);
but for above code it will give compile time error for float arguments.
Hope it clears all doubts.
First things first
Is it method overriding ?
No , since to override a method you need to replicate the complete method signature as pointed out in Brian Agnew's answer and as I explain below.
Is it overloading ?
Yes , Method "add" has an overloaded implementation in Class B.
Consider the following code:
class C{
public static void main(String args[]){
B a = new B();
a.add(2 , 3);
a.add(2.0 , 3.0);
}
}
class A {
public int add(int a , int b) {
System.out.print("INT ");
return a + b;
}
}
class B extends A {
public double add(double a , double b) {
System.out.print("Double ");
return a + b;
}
}
OUTPUT : INT Double
So , the method in Class B in your code overloads the add method that it inherits from its parent
Does it use Static Binding or Dynamic Binding ?
This is what makes me conclude that OP is confused.It is static binding because it is a overloaded function. The only way to think of dynamic binding would have been in below scenario
class C{
public static void main(String args[]){
A a = new B();
a.add(2.0 , 3.0);
}
}
class A {
public int add(int a , int b) {
System.out.println("A : INT");
return a + b;
}
}
class B extends A {
public int add(int a , int b) {
System.out.println("B : INT");
return a + b;
}
public double add(double a , double b) {
System.out.println("Double");
return a + b;
}
}
Output : B : INT
Here , the parent class A has a contract that says , "I have an add behaviour for ints" . class B inherits this add behaviour and makes it more specific and at the same time also provides a new behaviour where it can add doubles.
But class A has "no knowledge of this behaviour".
So an object of class A "cannot" add doubles. To do that you need a more specific type of A object i.e. a B object.
The method add() in class A is also available to class B by inheritance, therefore the method is overloaded in class by changing the data type from int, int to float, float.
The concept of Overloading comes in play if and only if the functions are in the same scope or class.
cz if this is the case of method overloading then for same method signature or same argument type the compiler gets confuse and must give compile time error .
but in the above program in class B if you pass the same argument in same order then according to overloading it must give error but it is not happening u can check it i already have.
It is the case of inheritance where through object reference if you call any method then the compiler will check it in child class ,if its not there then it will look into parent class that the above program is all about.
hope this is helpfull.

Overriding or overloading?

Guys I know this question is silly but just to make sure:
Having in my class method:
boolean equals(Document d)
{
//do something
}
I'm overloading this method nor overriding right? I know that this or similiar question will be on upcoming egzam and would be stupid to not get points for such a simple mistake;
Based on the code provided, we can't tell for sure whether you're overloading or overriding it.
You are most likely overloading the equals(Object o) method.
class A {
void method() {..}
}
class B extends A {
// this is overriding
void method() {..}
}
And
// this is overloading
class A {
void method(boolean b) {..}
void method(String arg) {..}
void method(int arg) {..}
}
P.S. you are using a bracket convention that is not widely accepted on the java world. In Java it is more common to place opening the curly bracket on the same.
You are not even overloading, since the other method is called equals. But if you add that s, you will be overloading equals. Although, to be precise, we talk about overloading if two (or more) methods with the same name but different signature are defined in the same class. In your case, it is trickier, since your equals with its different signature partly hides the original equals. Which is usually a bad thing, because this almost always leads to hard to understand behaviour, thus subtle bugs. Whenever someone calls equals on an instance of your class, depending on the parameter type the call may go to a different implementation of the method.
class Document {
public boolean equals(Document d)
{
//do something
}
}
Document doc1 = new Document();
Document doc2 = new Document();
String string = new String();
doc1.equals(doc2); // calls Document.equals
doc1.equals(string); // calls Object.equals!
You would be overriding Object.equals if you defined your method with the exact same signature as the original, i.e.
public boolean equals(Object obj) ...
In this case, both of the above calls to equals correctly execute Document.equals.
From the code you posted it could be either. If equal is defined in a superclass with the same parameter declarations then you are overriding it. If there is already a method called equal, but with different parameter types, you are overloading it.
On a related note, if you are using Java 5 and above and your intent is to override then it is highly recommended to use the #Override annotation before the method definition to indicate your intention. The wrong usage of this annotation (i.e. when you want to override and are not doing so) would flag a compile error.
As of Java 6 you can use the #Override annotation while defining methods that are
declared in an interface the class in implementing.
Overloading: same method name, same parameter list, different classes
Overriding: same method name, different parameter list, same or different classes.
Class A {
bool Equals(Document d) {...}
bool Equals(A a) {...} // overloaded method
}
Class B extends A {
bool Equals(Document d) {...} // overridden method
bool Equals(B b) {...} // overloaded method
}
One thing to note, the return type does not matter, it's the name of the method and the parameter list that make all the difference.

What's the nearest substitute for a function pointer in Java?

I have a method that's about ten lines of code. I want to create more methods that do exactly the same thing, except for a small calculation that's going to change one line of code. This is a perfect application for passing in a function pointer to replace that one line, but Java doesn't have function pointers. What's my best alternative?
Anonymous inner class
Say you want to have a function passed in with a String param that returns an int.
First you have to define an interface with the function as its only member, if you can't reuse an existing one.
interface StringFunction {
int func(String param);
}
A method that takes the pointer would just accept StringFunction instance like so:
public void takingMethod(StringFunction sf) {
int i = sf.func("my string");
// do whatever ...
}
And would be called like so:
ref.takingMethod(new StringFunction() {
public int func(String param) {
// body
}
});
EDIT: In Java 8, you could call it with a lambda expression:
ref.takingMethod(param -> bodyExpression);
For each "function pointer", I'd create a small functor class that implements your calculation.
Define an interface that all the classes will implement, and pass instances of those objects into your larger function. This is a combination of the "command pattern", and "strategy pattern".
#sblundy's example is good.
When there is a predefined number of different calculations you can do in that one line, using an enum is a quick, yet clear way to implement a strategy pattern.
public enum Operation {
PLUS {
public double calc(double a, double b) {
return a + b;
}
},
TIMES {
public double calc(double a, double b) {
return a * b;
}
}
...
public abstract double calc(double a, double b);
}
Obviously, the strategy method declaration, as well as exactly one instance of each implementation are all defined in a single class/file.
You need to create an interface that provides the function(s) that you want to pass around. eg:
/**
* A simple interface to wrap up a function of one argument.
*
* #author rcreswick
*
*/
public interface Function1<S, T> {
/**
* Evaluates this function on it's arguments.
*
* #param a The first argument.
* #return The result.
*/
public S eval(T a);
}
Then, when you need to pass a function, you can implement that interface:
List<Integer> result = CollectionUtilities.map(list,
new Function1<Integer, Integer>() {
#Override
public Integer eval(Integer a) {
return a * a;
}
});
Finally, the map function uses the passed in Function1 as follows:
public static <K,R,S,T> Map<K, R> zipWith(Function2<R,S,T> fn,
Map<K, S> m1, Map<K, T> m2, Map<K, R> results){
Set<K> keySet = new HashSet<K>();
keySet.addAll(m1.keySet());
keySet.addAll(m2.keySet());
results.clear();
for (K key : keySet) {
results.put(key, fn.eval(m1.get(key), m2.get(key)));
}
return results;
}
You can often use Runnable instead of your own interface if you don't need to pass in parameters, or you can use various other techniques to make the param count less "fixed" but it's usually a trade-off with type safety. (Or you can override the constructor for your function object to pass in the params that way.. there are lots of approaches, and some work better in certain circumstances.)
Method references using the :: operator
You can use method references in method arguments where the method accepts a functional interface. A functional interface is any interface that contains only one abstract method. (A functional interface may contain one or more default methods or static methods.)
IntBinaryOperator is a functional interface. Its abstract method, applyAsInt, accepts two ints as its parameters and returns an int. Math.max also accepts two ints and returns an int. In this example, A.method(Math::max); makes parameter.applyAsInt send its two input values to Math.max and return the result of that Math.max.
import java.util.function.IntBinaryOperator;
class A {
static void method(IntBinaryOperator parameter) {
int i = parameter.applyAsInt(7315, 89163);
System.out.println(i);
}
}
import java.lang.Math;
class B {
public static void main(String[] args) {
A.method(Math::max);
}
}
In general, you can use:
method1(Class1::method2);
instead of:
method1((arg1, arg2) -> Class1.method2(arg1, arg2));
which is short for:
method1(new Interface1() {
int method1(int arg1, int arg2) {
return Class1.method2(arg1, agr2);
}
});
For more information, see :: (double colon) operator in Java 8 and Java Language Specification §15.13.
You can also do this (which in some RARE occasions makes sense). The issue (and it is a big issue) is that you lose all the typesafety of using a class/interface and you have to deal with the case where the method does not exist.
It does have the "benefit" that you can ignore access restrictions and call private methods (not shown in the example, but you can call methods that the compiler would normally not let you call).
Again, it is a rare case that this makes sense, but on those occasions it is a nice tool to have.
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
class Main
{
public static void main(final String[] argv)
throws NoSuchMethodException,
IllegalAccessException,
IllegalArgumentException,
InvocationTargetException
{
final String methodName;
final Method method;
final Main main;
main = new Main();
if(argv.length == 0)
{
methodName = "foo";
}
else
{
methodName = "bar";
}
method = Main.class.getDeclaredMethod(methodName, int.class);
main.car(method, 42);
}
private void foo(final int x)
{
System.out.println("foo: " + x);
}
private void bar(final int x)
{
System.out.println("bar: " + x);
}
private void car(final Method method,
final int val)
throws IllegalAccessException,
IllegalArgumentException,
InvocationTargetException
{
method.invoke(this, val);
}
}
If you have just one line which is different you could add a parameter such as a flag and a if(flag) statement which calls one line or the other.
You may also be interested to hear about work going on for Java 7 involving closures:
What’s the current state of closures in Java?
http://gafter.blogspot.com/2006/08/closures-for-java.html
http://tech.puredanger.com/java7/#closures
New Java 8 Functional Interfaces and Method References using the :: operator.
Java 8 is able to maintain method references ( MyClass::new ) with "# Functional Interface" pointers. There are no need for same method name, only same method signature required.
Example:
#FunctionalInterface
interface CallbackHandler{
public void onClick();
}
public class MyClass{
public void doClick1(){System.out.println("doClick1");;}
public void doClick2(){System.out.println("doClick2");}
public CallbackHandler mClickListener = this::doClick;
public static void main(String[] args) {
MyClass myObjectInstance = new MyClass();
CallbackHandler pointer = myObjectInstance::doClick1;
Runnable pointer2 = myObjectInstance::doClick2;
pointer.onClick();
pointer2.run();
}
}
So, what we have here?
Functional Interface - this is interface, annotated or not with #FunctionalInterface, which contains only one method declaration.
Method References - this is just special syntax, looks like this, objectInstance::methodName, nothing more nothing less.
Usage example - just an assignment operator and then interface method call.
YOU SHOULD USE FUNCTIONAL INTERFACES FOR LISTENERS ONLY AND ONLY FOR THAT!
Because all other such function pointers are really bad for code readability and for ability to understand. However, direct method references sometimes come handy, with foreach for example.
There are several predefined Functional Interfaces:
Runnable -> void run( );
Supplier<T> -> T get( );
Consumer<T> -> void accept(T);
Predicate<T> -> boolean test(T);
UnaryOperator<T> -> T apply(T);
BinaryOperator<T,U,R> -> R apply(T, U);
Function<T,R> -> R apply(T);
BiFunction<T,U,R> -> R apply(T, U);
//... and some more of it ...
Callable<V> -> V call() throws Exception;
Readable -> int read(CharBuffer) throws IOException;
AutoCloseable -> void close() throws Exception;
Iterable<T> -> Iterator<T> iterator();
Comparable<T> -> int compareTo(T);
Comparator<T> -> int compare(T,T);
For earlier Java versions you should try Guava Libraries, which has similar functionality, and syntax, as Adrian Petrescu has mentioned above.
For additional research look at Java 8 Cheatsheet
and thanks to The Guy with The Hat for the Java Language Specification §15.13 link.
#sblundy's answer is great, but anonymous inner classes have two small flaws, the primary being that they tend not to be reusable and the secondary is a bulky syntax.
The nice thing is that his pattern expands into full classes without any change in the main class (the one performing the calculations).
When you instantiate a new class you can pass parameters into that class which can act as constants in your equation--so if one of your inner classes look like this:
f(x,y)=x*y
but sometimes you need one that is:
f(x,y)=x*y*2
and maybe a third that is:
f(x,y)=x*y/2
rather than making two anonymous inner classes or adding a "passthrough" parameter, you can make a single ACTUAL class that you instantiate as:
InnerFunc f=new InnerFunc(1.0);// for the first
calculateUsing(f);
f=new InnerFunc(2.0);// for the second
calculateUsing(f);
f=new InnerFunc(0.5);// for the third
calculateUsing(f);
It would simply store the constant in the class and use it in the method specified in the interface.
In fact, if KNOW that your function won't be stored/reused, you could do this:
InnerFunc f=new InnerFunc(1.0);// for the first
calculateUsing(f);
f.setConstant(2.0);
calculateUsing(f);
f.setConstant(0.5);
calculateUsing(f);
But immutable classes are safer--I can't come up with a justification to make a class like this mutable.
I really only post this because I cringe whenever I hear anonymous inner class--I've seen a lot of redundant code that was "Required" because the first thing the programmer did was go anonymous when he should have used an actual class and never rethought his decision.
The Google Guava libraries, which are becoming very popular, have a generic Function and Predicate object that they have worked into many parts of their API.
One of the things I really miss when programming in Java is function callbacks. One situation where the need for these kept presenting itself was in recursively processing hierarchies where you want to perform some specific action for each item. Like walking a directory tree, or processing a data structure. The minimalist inside me hates having to define an interface and then an implementation for each specific case.
One day I found myself wondering why not? We have method pointers - the Method object. With optimizing JIT compilers, reflective invocation really doesn't carry a huge performance penalty anymore. And besides next to, say, copying a file from one location to another, the cost of the reflected method invocation pales into insignificance.
As I thought more about it, I realized that a callback in the OOP paradigm requires binding an object and a method together - enter the Callback object.
Check out my reflection based solution for Callbacks in Java. Free for any use.
Sounds like a strategy pattern to me. Check out fluffycat.com Java patterns.
oK, this thread is already old enough, so very probably my answer is not helpful for the question. But since this thread helped me to find my solution, I'll put it out here anyway.
I needed to use a variable static method with known input and known output (both double). So then, knowing the method package and name, I could work as follows:
java.lang.reflect.Method Function = Class.forName(String classPath).getMethod(String method, Class[] params);
for a function that accepts one double as a parameter.
So, in my concrete situation I initialized it with
java.lang.reflect.Method Function = Class.forName("be.qan.NN.ActivationFunctions").getMethod("sigmoid", double.class);
and invoked it later in a more complex situation with
return (java.lang.Double)this.Function.invoke(null, args);
java.lang.Object[] args = new java.lang.Object[] {activity};
someOtherFunction() + 234 + (java.lang.Double)Function.invoke(null, args);
where activity is an arbitrary double value. I am thinking of maybe doing this a bit more abstract and generalizing it, as SoftwareMonkey has done, but currently I am happy enough with the way it is. Three lines of code, no classes and interfaces necessary, that's not too bad.
To do the same thing without interfaces for an array of functions:
class NameFuncPair
{
public String name; // name each func
void f(String x) {} // stub gets overridden
public NameFuncPair(String myName) { this.name = myName; }
}
public class ArrayOfFunctions
{
public static void main(String[] args)
{
final A a = new A();
final B b = new B();
NameFuncPair[] fArray = new NameFuncPair[]
{
new NameFuncPair("A") { #Override void f(String x) { a.g(x); } },
new NameFuncPair("B") { #Override void f(String x) { b.h(x); } },
};
// Go through the whole func list and run the func named "B"
for (NameFuncPair fInstance : fArray)
{
if (fInstance.name.equals("B"))
{
fInstance.f(fInstance.name + "(some args)");
}
}
}
}
class A { void g(String args) { System.out.println(args); } }
class B { void h(String args) { System.out.println(args); } }
Check out lambdaj
http://code.google.com/p/lambdaj/
and in particular its new closure feature
http://code.google.com/p/lambdaj/wiki/Closures
and you will find a very readable way to define closure or function pointer without creating meaningless interface or use ugly inner classes
Wow, why not just create a Delegate class which is not all that hard given that I already did for java and use it to pass in parameter where T is return type. I am sorry but as a C++/C# programmer in general just learning java, I need function pointers because they are very handy. If you are familiar with any class which deals with Method Information you can do it. In java libraries that would be java.lang.reflect.method.
If you always use an interface, you always have to implement it. In eventhandling there really isn't a better way around registering/unregistering from the list of handlers but for delegates where you need to pass in functions and not the value type, making a delegate class to handle it for outclasses an interface.
None of the Java 8 answers have given a full, cohesive example, so here it comes.
Declare the method that accepts the "function pointer" as follows:
void doCalculation(Function<Integer, String> calculation, int parameter) {
final String result = calculation.apply(parameter);
}
Call it by providing the function with a lambda expression:
doCalculation((i) -> i.toString(), 2);
If anyone is struggling to pass a function that takes one set of parameters to define its behavior but another set of parameters on which to execute, like Scheme's:
(define (function scalar1 scalar2)
(lambda (x) (* x scalar1 scalar2)))
see Pass Function with Parameter-Defined Behavior in Java
Since Java8, you can use lambdas, which also have libraries in the official SE 8 API.
Usage:
You need to use a interface with only one abstract method.
Make an instance of it (you may want to use the one java SE 8 already provided) like this:
Function<InputType, OutputType> functionname = (inputvariablename) {
...
return outputinstance;
}
For more information checkout the documentation: https://docs.oracle.com/javase/tutorial/java/javaOO/lambdaexpressions.html
Prior to Java 8, nearest substitute for function-pointer-like functionality was an anonymous class. For example:
Collections.sort(list, new Comparator<CustomClass>(){
public int compare(CustomClass a, CustomClass b)
{
// Logic to compare objects of class CustomClass which returns int as per contract.
}
});
But now in Java 8 we have a very neat alternative known as lambda expression, which can be used as:
list.sort((a, b) -> { a.isBiggerThan(b) } );
where isBiggerThan is a method in CustomClass. We can also use method references here:
list.sort(MyClass::isBiggerThan);
The open source safety-mirror project generalizes some of the above mentioned solutions into a library that adds functions, delegates and events to Java.
See the README, or this stackoverflow answer, for a cheat sheet of features.
As for functions, the library introduces a Fun interface, and some sub-interfaces that (together with generics) make up a fluent API for using methods as types.
Fun.With0Params<String> myFunctionField = " hello world "::trim;`
Fun.With2Params<Boolean, Object, Object> equals = Objects::equals;`
public void foo(Fun.With1ParamAndVoid<String> printer) throws Exception {
printer.invoke("hello world);
}
public void test(){
foo(System.out::println);
}
Notice:
that you must choose the sub-interface that matches the number of parameters in the signature you are targeting. Fx, if it has one parameter, choose Fun.With1Param.
that Generics are used to define A) the return type and B) the parameters of the signature.
Also, notice that the signature of the Method Reference passed to the call to the foo() method must match the the Fun defined by method Foo. If it do not, the compiler will emit an error.

Categories

Resources