What is the point of naming a function in a Functional Interface? - java

I'm reading about Functional Interfaces in Java in this tutorial
Here is the specific code that is bothering me:
public interface FunctionalInterfaceTest{
void display();
}
//Test class to implement above interface
public class FunctionInterfaceTestImpl {
public static void main(String[] args){
//Old way using anonymous inner class
FunctionalInterfaceTest fit = new FunctionalInterfaceTest(){
public void display(){
System.out.println("Display from old way");
}};
fit.display();//outputs: Display from old way
//Using lambda expression
FunctionalInterfaceTest newWay = () -> {System.out.println("Display from new Lambda Expression");}
newWay.display();//outputs : Display from new Lambda Expression
}
}
I don't understand. What is the point of having a function called display(). It doesn't do anything and is never defined. Yes I understand that when you call the single method in a Functional Interface, it executes the code in the lambda expression that was created in it.
But here's my question; if all functional interfaces essentially just run lambda expressions, then why not just save us the time of naming the single method, and just make it permanently exe()? What is the point of offering the Functional Interface syntax and customization if it adds almost nothing. A far better syntax for me would be:
#FunctionalInterface MyInterface
MyInterface mine = () -> {System.out.print("Mine!!")}
mine.exe();
This is much more standard, shorter and easier to understand.
Is this a brilliant idea or am I missing something?

What is the point of having a function called display(). It doesn't do anything and is never defined.
It's still an interface at heart, and it's still subject to the same wonky rules that an interface would be if you weren't using lambdas.
The display method could be defined on a concrete class in the exact same manner...
public class Concrete implements FunctionalInterfaceTest {
#Override
public void display() {
System.out.println("Displayed! W00t!");
}
}
...and we would have done the exact same amount of work: we have an interface which only generates side effects. This is not desirable.
The real power of this comes in when you want to actually do pure operations on objects or primitives, but you don't want to define concrete classes just to specify what those operations actually are.
Let's suppose we wanted a functional interface to give us the difference of two Numbers.
#FunctionalInterface
public interface NumberAdder<T extends Number> {
T result (T firstValue, T secondValue);
}
I can then use it in this manner:
NumberAdder<Integer> numberAdder = (x, y) -> x + y;
NumberAdder<Long> longAdder = (x, y) -> x + y;
// From (x, y) -> x.add(y);, the below is shortened to a method reference
NumberAdder<BigInteger> bigIntAdder = BigInteger::add;
It's by and large syntactic sugar for the subclassing - anonymous or not - that would have to happen with the interface. Instead, I can define the contract once and define the behavior in whatever scenario/context I need it to be in.
System.out.println(numberAdder.result(10, 20));
System.out.println(longAdder.result(172893791273L, 979789123L));
System.out.println(bigIntAdder.result(BigInteger.valueOf(172917298179821L), BigInteger.valueOf(17232891L)));
It is still your responsibility to define the behavior. You could easily write this:
NumberAdder<BigInteger> bigIntAdder2 = BigInteger::divide;
...and that would still be just fine with the interface. You need to be careful that your intended use isn't abused when it comes time to actually implement it.
Don't treat lambdas as anything that they aren't. By and large, you're replacing anonymous classes with a lambda expression. If you want to get fancy with it you're more than welcome to, but don't assume that every functional interface follows the same conventions between them.

Related

Are there dangers in making an existing Java interface functional?

As a rule, in the context of a large project, is it considered safe to take make an existing, ubiquitously used interface into a functional interface?
E.g., given an existing interface and class:
public interface Interface {
public double calculateSomething(double x);
public void doSomething();
}
which is implemented by
class InterfaceImplementer implements Interface {
public double calculateSomething(double x) {
return 2 * x;
}
public void doSomething() {
// insert specific behavior here
}
}
can I safely change the interface by defining all but one method as default:
public interface Interface {
public double calculateSomething(double x);
default void doSomething() {
// insert some default behavior here
}
}
So that I can go from defining an object as
Interface object = new InterfaceImplementer() {
#Override
public double calculateSomething(double x) {
return 2 * x;
}
};
to
Interface object = (x) -> 2 * x;
while still being able to define objects in the old, tedious way.
From what I can tell, this runs no risk of upsetting any existing code, and I've made such a change to a large project and had no runtime or compile errors. But I want some confirmation whether this matches up with common knowledge and best practices.
Any interface that only has a single non-default method (only one method needs to be implemented in a class) is by definition a functional interface. This is a good rule!
However, a #FunctionalInterface annotation has the advantage of enforcing the "only one method in the interface for a functional interface"-rule. So if you added it to your original two-method interface, you would have gotten a compiler error. Therefore by explicitly adding #FunctionalInterface you declare your intent and make your code more clear to future maintainers.
On java code level, I can think of one problem: since this interface already had contained 2 methods at some point in the past, you may want to add another method to it later on. You won't be able to add another method to a functional interface, since it has to remain a functional interface so you can use it as a functional interface. You will have to create an interface that inherits from this one. Which leads me to the main point.
It may have been logical to have those 2 methods in one interface before, but is it really logical now? Refactor the code, separate the interfaces; either make one extend another or use an interface that inherits from both, your call. If the interface is to be used as a functional one, make it functional. It will be clean. It will be understandable. You will be able to add methods to one of those interfaces in the future without further refactoring.
The Java API states:
However, the compiler will treat any interface meeting the definition of a functional interface as a functional interface regardless of whether or not a FunctionalInterface annotation is present on the interface declaration.
Therefore there is no risk to add that annotation.
Well, it's not the #Functional that might break anything, but adding a default implementation may lead to compilation errors for abstract classes that implement or interfaces that extend multiple interfaces declaring methods with override-equivalent signatures:
The following compiles fine:
interface I {
void a();
}
interface J {
void a();
}
interface K extends I, J {}
while this doesn't:
interface I {
default void a() {}
}
interface J {
void a();
}
interface K extends I, J {}
The default method a() inherited from I conflicts with another method inherited from J
So if you do this in a library, code using this may fail to compile after the change.

InputStream and OutputStream in java/Android [duplicate]

I am learning java concepts.
I got a doubt in java inheritance concept.
In inheritance we can assign subclass instance to a base class reference
and with that we can access only base class function.
and we can assign any subclass instance in the hierarchy of inheritance to base class reference.For an type of instance assigning to a particular base class reference we can access only base class functions and i didn't find any difference.
Can any one give me actual concept
why we have to assign subclass instances to base class references?
what is the need to do that?
Instead we can access those base class functions from subclass reference only know.
Explain by considering a particular base class and many subclasses in the hierarchy.
The reason why you may want to do this is to create more robust designs. Take for example the Collections Framework in Java. You have a List interface and then you have two implementations, ArrayList and LinkedList.
You can write your program to use a LinkedList specifically or an ArrayList specifically. However, your program then depends on those specific implementations.
If you write your program to depend on the super type, List, instead then your program can work for either of the List implementations. Lets say you want to write a method that does something to a List and you wrote this:
public void doSomething(ArrayList a){}
This method can only be called with an ArrayList, not a LinkedList. Suppose that you wanted to do the same thing with a LinkedList? Do you then duplicate your code? No.
public void doSomething(List l){}
Will be able to accept either type of List.
The principle behind this is program to an interface not an implementation. That is, List defines the functions of ALL lists.
There are many many examples of this usage.
Inheritance and Polymorphism are cornerstones of object-oriented programming and serve a few different purposes, in short:
Code reuse by extending a base class with specific functionality,
Interface design by providing an abstract set of functionality, which where different implementations are tailored to different requirements and
Encapsulation by hiding specific functionality, which isn't needed in certain contexts
among others.
The last point also highlights, why one might use a restricted set of functionality, even in a case the actual implementation provides more than that. Take for example the Collection interface. By using this interface, we focus on methods like isEmpty, contains or size but not the actual implementation.
What you've described is the essence of polymorphism. It's a word from the Greek that means "many forms".
If I gave you a simple hierarchy like this, you can see how the test code can get different calculation implementations out of each object without concerning itself about what kind of Shape it was dealing with:
public interface Shape
{
double calculateArea();
}
class Circle implements Shape
{
private double radius;
Circle(double r) { this.radius = r; }
public double calculateArea() { return Math.PI*radius*radius; }
}
class Square implements Shape
{
private double side;
Square(double s) { this.side = s; }
public double calculateArea() { return side*side; }
}
// This would be a separate JUnit or TestNG annotated test.
public class ShapeTest
{
#Test
public void testCalculateArea()
{
Map<Shape, Double> expected = new HashMap<Shape, Double>()
{{
put(new Circle(1.0), Math.PI);
put(new Square(1.0), 1.0);
}};
for (Shape shape : expected.keySet())
{
Assert.assertEquals(expected.get(shape), shape.calculateArea());
}
}
}
Polymorphism.
I am a method that gives you a List<String>. All you need to know about the thing I've actually given you is that it's a list and has the behaviour and semantics of a list, i.e. you can put things in it, it'll maintain their ordering, and you can iterate over it.
What you don't need to know is how I'm storing things, how I'm making them accessible, etc. That's not important. For all you care, it could be a LinkedList<String>, an ArrayList<String> or something entirely new. Suffice it to say, I've picked something, and you can happily use it.
You're absolutely right that when you're using inheritance to extend classes and add new behaviour, then you need to reference the subclass to be able to access it. The two approaches are somewhat complimentary, but different, use cases.
Let us say Vehicle is the base class and Car and Plane are subclasses. Let us say Vehicle has has a method move().
Car overrides this by going on road. Plane overrides this by flying.
Why move() should be part of Vehicle base class?
Because any Vehicle can move(). But we can't implement move() in Vehicle because all vehicles doesn't move the same way i.e. there is no common behavior. We still want this in the base class so that we can have polymorphic behavior i.e. we can write code like below. As you can see there is only one method called runVehicle(...) that can work on any Vehicle class.
void runVehicle(Vehicle v)
{
v.move();
}
Car c=new Car();
runVehicle(c);
Plane p=new Plane();
runPlane(p);
There is no real need to do that, except when the API demands it. For example, if in a particular API or code library there is a
void ReallyUsefulFunction(BaseClass instance)
that you would like to use, you can derive a class fom BaseClass and implement its methods in the SubClass. Then you can now pass the subclass to the function.
Still, technically, you could implement your own
void MyReallyUsefulFunction(MyClass instance)
which imitates the same functionality. But like what MYYM had explained, the benefits of code reuse etc. can be huge, and that is when you will want to take advantage of polymorphism.

What are functional interfaces used for in Java 8?

I came across a new term in Java 8: "functional interface". I could only find one use of it while working with lambda expressions.
Java 8 provides some built-in functional interfaces and if we want to define any functional interface then we can make use of the #FunctionalInterface annotation. It will allow us to declare only a single method in the interface.
For example:
#FunctionalInterface
interface MathOperation {
int operation(int a, int b);
}
How useful it is in Java 8 other than just working with lambda expressions?
(The question here is different from the one I asked. It is asking why we need functional interfaces while working with lambda expressions. My question is: What are the other uses of functional interfaces besides use with lambda expressions?)
#FunctionalInterface annotation is useful for compilation time checking of your code. You cannot have more than one method besides static, default and abstract methods that override methods in Object in your #FunctionalInterface or any other interface used as a functional interface.
But you can use lambdas without this annotation as well as you can override methods without #Override annotation.
From docs
a functional interface has exactly one abstract method. Since default
methods have an implementation, they are not abstract. If an interface
declares an abstract method overriding one of the public methods of
java.lang.Object, that also does not count toward the interface's
abstract method count since any implementation of the interface will
have an implementation from java.lang.Object or elsewhere
This can be used in lambda expression:
public interface Foo {
public void doSomething();
}
This cannot be used in lambda expression:
public interface Foo {
public void doSomething();
public void doSomethingElse();
}
But this will give compilation error:
#FunctionalInterface
public interface Foo {
public void doSomething();
public void doSomethingElse();
}
Invalid '#FunctionalInterface' annotation; Foo is not a functional
interface
The documentation makes indeed a difference between the purpose
An informative annotation type used to indicate that an interface type declaration is intended to be a functional interface as defined by the Java Language Specification.
and the use case
Note that instances of functional interfaces can be created with lambda expressions, method references, or constructor references.
whose wording does not preclude other use cases in general. Since the primary purpose is to indicate a functional interface, your actual question boils down to “Are there other use cases for functional interfaces other than lambda expressions and method/constructor references?”
Since functional interface is a Java language construct defined by the Java Language Specification, only that specification can answer that question:
JLS §9.8. Functional Interfaces:
…
In addition to the usual process of creating an interface instance by declaring and instantiating a class (§15.9), instances of functional interfaces can be created with method reference expressions and lambda expressions (§15.13, §15.27).
So the Java Language Specification doesn’t say otherwise, the only use case mentioned in that section is that of creating interface instances with method reference expressions and lambda expressions. (This includes constructor references as they are noted as one form of method reference expression in the specification).
So in one sentence, no, there is no other use case for it in Java 8.
As others have said, a functional interface is an interface which exposes one method. It may have more than one method, but all of the others must have a default implementation. The reason it's called a "functional interface" is because it effectively acts as a function. Since you can pass interfaces as parameters, it means that functions are now "first-class citizens" like in functional programming languages. This has many benefits, and you'll see them quite a lot when using the Stream API. Of course, lambda expressions are the main obvious use for them.
Not at all. Lambda expressions are the one and only point of that annotation.
A lambda expression can be assigned to a functional interface type, but so can method references, and anonymous classes.
One nice thing about the specific functional interfaces in java.util.function is that they can be composed to create new functions (like Function.andThen and Function.compose, Predicate.and, etc.) due to the handy default methods they contain.
An interface with only one abstract method is called Functional Interface.
It is not mandatory to use #FunctionalInterface, but it’s best practice to use it with functional interfaces to avoid addition of extra methods accidentally. If the interface is annotated with #FunctionalInterface annotation and we try to have more than one abstract method, it throws compiler error.
package com.akhi;
#FunctionalInterface
public interface FucnctionalDemo {
void letsDoSomething();
//void letsGo(); //invalid because another abstract method does not allow
public String toString(); // valid because toString from Object
public boolean equals(Object o); //valid
public static int sum(int a,int b) // valid because method static
{
return a+b;
}
public default int sub(int a,int b) //valid because method default
{
return a-b;
}
}
Functional Interface:
Introduced in Java 8
Interface that contains a "single abstract" method.
Example 1:
interface CalcArea { // --functional interface
double calcArea(double rad);
}
Example 2:
interface CalcGeometry { // --functional interface
double calcArea(double rad);
default double calcPeri(double rad) {
return 0.0;
}
}
Example 3:
interface CalcGeometry { // -- not functional interface
double calcArea(double rad);
double calcPeri(double rad);
}
Java8 annotation -- #FunctionalInterface
Annotation check that interface contains only one abstract method. If not, raise error.
Even though #FunctionalInterface missing, it is still functional interface (if having single abstract method). The annotation helps avoid mistakes.
Functional interface may have additional static & default methods.
e.g. Iterable<>, Comparable<>, Comparator<>.
Applications of Functional Interface:
Method references
Lambda Expression
Constructor references
To learn functional interfaces, learn first default methods in interface, and after learning functional interface, it will be easy to you to understand method reference and lambda expression
You can use lambda in Java 8
public static void main(String[] args) {
tentimes(inputPrm - > System.out.println(inputPrm));
//tentimes(System.out::println); // You can also replace lambda with static method reference
}
public static void tentimes(Consumer myFunction) {
for (int i = 0; i < 10; i++)
myFunction.accept("hello");
}
For further info about Java Lambdas and FunctionalInterfaces
#FunctionalInterface is a new annotation are released with Java 8 and provide target types for lambda expressions and it used on compilation time checking of your code.
When you want to use it :
1- Your interface must not have more than one abstract methods, otherwise compilation error will be given.
1- Your interface Should be pure, which means functional interface is intended to be implemented by stateless classes, exmple of pure is Comparator interface because its not depend on the implementers state, in this case No compilation error will be given, but in many cases you will not be able to use lambda with this kind of interfaces
The java.util.function package contains various general purpose functional interfaces such as Predicate, Consumer, Function, and Supplier.
Also please note that you can use lambdas without this annotation.
Beside other answers, I think the main reason to "why using Functional Interface other than directly with lambda expressions" can be related to nature of Java language which is Object Oriented.
The main attributes of Lambda expressions are: 1. They can be passed around 2. and they can executed in future in specific time (several times). Now to support this feature in languages, some other languages deal simply with this matter.
For instance in Java Script, a function (Anonymous function, or Function literals) can be addressed as a object. So, you can create them simply and also they can be assigned to a variable and so forth. For example:
var myFunction = function (...) {
...;
}
alert(myFunction(...));
or via ES6, you can use an arrow function.
const myFunction = ... => ...
Up to now, Java language designers have not accepted to handle mentioned features via these manner (functional programming techniques). They believe that Java language is Object Oriented and therefore they should solve this problem via Object Oriented techniques. They don't want to miss simplicity and consistency of Java language.
Therefore, they use interfaces, as when an object of an interface with just one method (I mean functional interface) is need you can replace it with a lambda expression. Such as:
ActionListener listener = event -> ...;
Functional Interfaces: An interface is called a functional interface if it has a single abstract method irrespective of the number of default or static methods. Functional Interface are use for lamda expression. Runnable, Callable, Comparable, Comparator are few examples of Functional Interface.
KeyNotes:
Annotation #FunctionalInterface is used(Optional).
It should have only 1 abstract method(irrespective of number of default and static
methods).
Two abstract method gives compilation error(Provider #FunctionalInterface annotation is
used).
This thread talks more in detail about what benefit functional Interface gives over anonymous class and how to use them.

Why should I reference the base class when I can access all the methods just as well by referencing the subclass?

I am learning java concepts.
I got a doubt in java inheritance concept.
In inheritance we can assign subclass instance to a base class reference
and with that we can access only base class function.
and we can assign any subclass instance in the hierarchy of inheritance to base class reference.For an type of instance assigning to a particular base class reference we can access only base class functions and i didn't find any difference.
Can any one give me actual concept
why we have to assign subclass instances to base class references?
what is the need to do that?
Instead we can access those base class functions from subclass reference only know.
Explain by considering a particular base class and many subclasses in the hierarchy.
The reason why you may want to do this is to create more robust designs. Take for example the Collections Framework in Java. You have a List interface and then you have two implementations, ArrayList and LinkedList.
You can write your program to use a LinkedList specifically or an ArrayList specifically. However, your program then depends on those specific implementations.
If you write your program to depend on the super type, List, instead then your program can work for either of the List implementations. Lets say you want to write a method that does something to a List and you wrote this:
public void doSomething(ArrayList a){}
This method can only be called with an ArrayList, not a LinkedList. Suppose that you wanted to do the same thing with a LinkedList? Do you then duplicate your code? No.
public void doSomething(List l){}
Will be able to accept either type of List.
The principle behind this is program to an interface not an implementation. That is, List defines the functions of ALL lists.
There are many many examples of this usage.
Inheritance and Polymorphism are cornerstones of object-oriented programming and serve a few different purposes, in short:
Code reuse by extending a base class with specific functionality,
Interface design by providing an abstract set of functionality, which where different implementations are tailored to different requirements and
Encapsulation by hiding specific functionality, which isn't needed in certain contexts
among others.
The last point also highlights, why one might use a restricted set of functionality, even in a case the actual implementation provides more than that. Take for example the Collection interface. By using this interface, we focus on methods like isEmpty, contains or size but not the actual implementation.
What you've described is the essence of polymorphism. It's a word from the Greek that means "many forms".
If I gave you a simple hierarchy like this, you can see how the test code can get different calculation implementations out of each object without concerning itself about what kind of Shape it was dealing with:
public interface Shape
{
double calculateArea();
}
class Circle implements Shape
{
private double radius;
Circle(double r) { this.radius = r; }
public double calculateArea() { return Math.PI*radius*radius; }
}
class Square implements Shape
{
private double side;
Square(double s) { this.side = s; }
public double calculateArea() { return side*side; }
}
// This would be a separate JUnit or TestNG annotated test.
public class ShapeTest
{
#Test
public void testCalculateArea()
{
Map<Shape, Double> expected = new HashMap<Shape, Double>()
{{
put(new Circle(1.0), Math.PI);
put(new Square(1.0), 1.0);
}};
for (Shape shape : expected.keySet())
{
Assert.assertEquals(expected.get(shape), shape.calculateArea());
}
}
}
Polymorphism.
I am a method that gives you a List<String>. All you need to know about the thing I've actually given you is that it's a list and has the behaviour and semantics of a list, i.e. you can put things in it, it'll maintain their ordering, and you can iterate over it.
What you don't need to know is how I'm storing things, how I'm making them accessible, etc. That's not important. For all you care, it could be a LinkedList<String>, an ArrayList<String> or something entirely new. Suffice it to say, I've picked something, and you can happily use it.
You're absolutely right that when you're using inheritance to extend classes and add new behaviour, then you need to reference the subclass to be able to access it. The two approaches are somewhat complimentary, but different, use cases.
Let us say Vehicle is the base class and Car and Plane are subclasses. Let us say Vehicle has has a method move().
Car overrides this by going on road. Plane overrides this by flying.
Why move() should be part of Vehicle base class?
Because any Vehicle can move(). But we can't implement move() in Vehicle because all vehicles doesn't move the same way i.e. there is no common behavior. We still want this in the base class so that we can have polymorphic behavior i.e. we can write code like below. As you can see there is only one method called runVehicle(...) that can work on any Vehicle class.
void runVehicle(Vehicle v)
{
v.move();
}
Car c=new Car();
runVehicle(c);
Plane p=new Plane();
runPlane(p);
There is no real need to do that, except when the API demands it. For example, if in a particular API or code library there is a
void ReallyUsefulFunction(BaseClass instance)
that you would like to use, you can derive a class fom BaseClass and implement its methods in the SubClass. Then you can now pass the subclass to the function.
Still, technically, you could implement your own
void MyReallyUsefulFunction(MyClass instance)
which imitates the same functionality. But like what MYYM had explained, the benefits of code reuse etc. can be huge, and that is when you will want to take advantage of polymorphism.

Closure and Callbacks

Is there any other way in java to implement call backs apart from inner classes? What is the difference between callbacks and closures?
Closure is how you build it, callback is how you use it.
A callback can be implemented as a closure (in languages that have them) or an implementation of an interface (in Java, as an anonymous inner class or a regular class).
Callback means that you pass a piece of code to a function, so that the function can call that piece of code later. It is a special kind of parameter.
The piece of code can be a function pointer or a closure or an object with well-known methods, depending on what the language offers.
Both closures and anonymous inner classes (and others) can be used as callbacks. A callback is just some code which is passed as an argument to other code.
A big difference of closures, compared to Java's anonymous inner classes, is that (in imperative languages) a closure can modify the variables of the surrounding scope. Wikipedia gives the following example:
var f, g;
function foo() {
var x = 0;
f = function() { return ++x; };
g = function() { return --x; };
x = 1;
alert('inside foo, call to f(): ' + f()); // "2"
}
foo();
alert('call to g(): ' + g()); // "1"
alert('call to f(): ' + f()); // "2"
A callback is just any executable code that is passed as a parameter to other code. In frequent usage, that executable code is a closure, but it's not necessarily.
The word closure is somewhat abused and many people just use it as a synonym for "anonymous function", but at least according to Wikipedia, that's a misuse of the term. The Wikipedia article explains this better than I can do quickly.
If you need closures in java you could try lambdaj. Here you can see how it allows to define closures through a very straightforward DSL.
I don't think so.
If there is, then it is probably inferior in some way, otherwise anonymous inner classes wouldn't be widely used.
There is no difference.
Closures can be defined as a block of code holding parent context that can be executed with ease.
In fact, the only difference I know between those is the ease of writing. A typical groovy/ruby closure is indeed smaller to write than a Java anonymous class.
However, considering Java framworks like guava and there liberal use of anonymous classes/interfaces, particularly for typical closures use cases like filter (comparing with groovy's implementation), I can say there is absolutely no design difference.
Sadly the only reasonable way is inner/anonymous classes.
You can also do it with reflection, but that usually is slower and harder in maintenance (no syntax highlighting, hard to find references in IDE etc.). An example:
myButton.addActionListener(EventHandler.create(ActionListener.class, handlerObject, "onClick"));
For now anonymous classes are the best way of handling callbacks in Java. However this is likely to change come Java 7 which will implement closures. http://en.wikipedia.org/wiki/Closure_(computer_science)
Here it is two implementations that uses closures and callbacks.
http://www.caglargonul.com/2013/04/05/playing-with-closures-in-java-7/
http://www.caglargonul.com/2013/04/05/java7-callback-implementation/
And here is a better example (can be found here http://www.caglargonul.com/2013/04/10/is-it-really-a-closure-yes-it-is/ ) for understanding what closure is. The key is that
a closure comes with a referencing environment not just a function code.
The best way to implement a closure in Java 7 and below is using an interface. In this example a callback is implemented as closure.
You first declare your interface which will hold your closure.
public interface CallBack {
void m(int e);
}
And lets add a class responsible for holding an array of closures, two public methods for adding and removing closures and a public function which will call the functions inside the closures when an event occurs.
public class CCallBack {
List<CallBack> cbs = new ArrayList<>();
public void registerCallBack(CallBack f){
cbs.add(f);
}
public void removeCallBack(CallBack f){
if(cbs.contains(f)){
cbs.remove(f);
}
}
public void onAction(int i){
for (CallBack callBack : cbs) {
callBack.m(i);
}
}
}
And here is the magical part. See the referencing environment in action.
public class CallBackTester {
CCallBack cb = new CCallBack();
#Test
public void test_callback(){
CallBack cb1 = new CallBack() {
int x = 1;
#Override
public void m(int e) {
if(e==1){
System.out.println("You register this callback " + x + " time/times");
x++;
}
}
};
cb.registerCallBack(cb1);
cb.registerCallBack(cb1);
cb.registerCallBack(cb1);
cb.removeCallBack(cb1);
cb.onAction(1);
}
}
Above when we declare cb1 we are adding a referencing environment which consists of the variable x. When we call the function inside this closure we are incrementing this variable by one. If it was a normal function, x would have been declared as 1 when we call the function. BUT IT IS NOT A NORMAL FUNCTION. IT IS A CLOSURE. So x is not declared every time we call the function in the closure. As you can see from the output every time we call it, x is incrementing.
You register this callback 1 time/times
You register this callback 2 time/times

Categories

Resources