Delegates - how to? - java

I'm trying to use interfaces in my android java project. Callback interfaces seems to be the answer to C# delegates, but I can't get my head around it, I've read other similar questions, but again, I can't get it to fit my needs or get it to work. What I need is to call a function in Class A that is pass as a parameter to Class B. When class B finishes a task, returns the result to A by calling the function previously saved in a variable:
class A {
B myBClass;
public A() {
myBClass = new B();
myBClass.doSomething(ResultFunction);
//Continue doing other tasks
}
public void ResultFunction(<result parameters>) {
//do something with the result from the task in myBClass
}
}
class B {
Function myCallback;
public B() {
}
public void doSomething(ResultFunction) {
myCallback = callback;
//does something
SomethingFinished();
}
private void SomethingFinished() {
myCallback.call(<result of doSomething>);
}
}

There are 2 ways to do it:
1) Use anonymous class:
Remove ResultFunction argument from doSomething method in class B
And reimplement it in class A
public A() {
myBClass = new B() {
#Override
public void doSomething() {
super.doSomething();
//do here what you need what you want to do in B class
}
}
myBClass.doSomething();
//Continue doing other tasks
}
2) UseCallable interface
interface Callable {
public void call();
}
pass it instead of ResultFunction
class A {
B myBClass;
Callable callable = new Callable {
#Override
public void call() {
//do here what you need what you want to do in B class
}
}
public A() {
myBClass = new B();
myBClass.doSomething(callable);
//Continue doing other tasks
}
}
class B {
Callable myCallback;
public B() {
}
public void doSomething(Callable callable) {
myCallback = callable;
//does something
SomethingFinished();
}
private void SomethingFinished() {
myCallback.call();
}
}
With lambdas it can look like a bit better
public A() {
myBClass = new B();
myBClass.doSomething(()->{
//do here what you need what you want to do in B class
});
//Continue doing other tasks
}

I do not understand why can't you just do the following:
public class A {
private B myBClass;
public A() {
myBClass = new B();
Result result = myBClass.doSomething();
resultFunction(result)
//Continue doing other tasks
}
public void resultFunction(Result result) {
//do something with the result from the task in myBClass
}
}
public class B {
public B() {
}
public Result doSomething() {
//does something
}
}
If, for whatever reason, you must do that, you can do it easily in Java 8 like this:
public class A {
B myBClass;
public A() {
myBClass = new B();
myBClass.doSomething(A::resultFunction);
//Continue doing other tasks
}
public void resultFunction(Result result) {
//do something with the result from the task in myBClass
}
}
public class B {
private Consumer<Result> myCallback;
public B() {
}
public void doSomething(Consumer<Result> callback) {
myCallback = callback;
//does something
myCallback.accept(result);
}
}

Related

Java simple callback

It is basic problem. I have class A which gives some task to class B. When class B finish the tast it must notify class A. I want register A class method as callback in class B.
I really want do it in this way, not by observer pattern with interface Observable.
public class A
{
public void A()
{
B b = new B()
b.registerCallback(callback);
}
private void callback()
{
}
}
public class B
{
private ???? callbackoNotify;
public class registerCallback(??? callback)
{
callbackoNotify = callback;
}
public void notify()
{
callback();
}
}
You can define an interface for the callback.
interface Callback{
void call();
}
Then, let class A implement it.
class A implements Callback{
private B b;
public A(){
b = new B();
b.registerCallback(this);
}
// Implementation of the callback interface
public void call(){
}
}
Then, let class B to handle the callback.
public class B
{
private Callback callbackoNotify;
public class registerCallback(Callback callback)
{
callbackoNotify = callback;
}
public void notify()
{
callbackNotify.call();
}
}
But in the above scenario, callbackNotify can be null. Therefore, it is better if you can pass that callback in the constructor to B.
Hope you got the idea.
You can do this without callbacks as well. Here's an example:
A a = ...
B b = ...
Let's say b has a doTask method like this:
public void doTask(Runnable task);
A can now call it like this:
b.doTask(() -> {System.out.println("Hi There");});
However, A will not be informed when the task gets completed. You could simply change the task like this:
Runnable taskForB = () -> {System.out.println("Hi There");};
Runnable wrapperForTaskWithCallback = () -> {
taskForB.run();
taskWasFinished();
};
And then run the wrapper task instead:
b.doTask(wrapperForTaskWithCallback);
And give A a method:
public void taskWasFinished();

Effective design for related classes that use unrelated classes

I have following situation and would like to know the best way to design my solution
public abstract class A {
public abstract A getHelper();
public abstract void launchHandle();
public static A initHelper(String condition) throws Exception {
if ( condition == 'xyz') {
return C.getHelper();
} else {
return B.getHelper();
}
}
}
public class B extends A {
protected static A b;
#Override
public A getHelper() {
b = new B();
return b;
}
#Override
public void launchHandle() {
System.out.println("Launching Handle");
}
public String getName() {
return "I am from Class B";
}
}
public class C extends A {
protected static A c;
#Override
public A getHelper() {
c = new C();
return c;
}
#Override
public void launchHandle() {
System.out.println("Launching Handle from C");
}
public String getValue() {
return "I am from Class C";
}
}
**Executor class**
public class Executor {
public static void main(String[] args) {
A aa = a.initHelper(condition);
}
}
Now in the above approach, i am unable to access methods like aa.getName() from Class B OR aa.getValue() from Class C, which makes sense. However how to get these methods in executor class? Executor does not know anything about Class B & C and should not know. Executor is only aware of Class A, but want to access methods SubClass methods from B & C which are extended from Class A.
Please help design this and what could be best way to solve this.
Thanks in advance.
Executor is only aware of Class A, but want to access methods SubClass methods from B & C which are extended from Class A.
If you take a closer look at your code, you will notice that the only contract constant across all your classes is the launchHandle method (baring getHelper and initHelper which are simply used for instantiating the right subclass). There is no real relation between B and C other than the fact that their instantiation is controlled by A.
This is how I would consider approaching the problem :
Executor Factory
Make Executor an abstract class rather than making it the entry point of your program :
public abstract class Executor {
public abstract void performTask();
public static void execute(String condition) {
Executor executor = null;
if ( condition.equals("xyz")) {
executor = new AExector();
} else {
executor = new BExecutor();
}
executor.performTask();
}
}
Executor implementations
Create a different implementation for operating on B called BExecutor :
public class BExecutor extends Executor {
public void performTask() {
System.out.println("launching handle from B");
//create or get data to perform the task on
B b = new B();
String name = b.getName();
System.out.println("I am from "+name);
}
}
Create a different implementation for operating on C called CExecutor :
public class CExecutor extends Executor {
public void performTask() {
System.out.println("launching handle from C");
//create or get data to perform the task on
C c = new C();
String value = c.getValue();
System.out.println("I am from "+value);
}
}
Your main method can then look like this :
public static void main(String []args) {
Executor executor = Executor.execute(condition);
}
And for some reason, if you do find some common contract between B and C, you an always create an interface which both B and C can implement and use a reference of this interface instead of using a B or C reference.
Add getName and getValue to A as abstract methods.

Java extends generic prototype

I have few classes that implements some interface. Now I want to create new class, which can extend one of them, based on runtime calculation while using interfaces methods. Let's talk in code:
public interface Interface {
public void doSomething();
}
public class A implements Interface {
#Override
public void doSomething() {
System.out.println("hello");
}
}
public class B implements Interface {
#Override
public void doSomething() {
System.out.println("hi");
}
}
These are existing classes, so now I need to do something like this (which is not working of course):
public class C<T extends Interface> extends T {
public void doSomethingElse() {
this.doSomething();
}
public static void main(String[] args) {
C c;
if(isSomethingLoaded) {
c = new C<A>();
} else {
c = new C<B>();
}
c.doSomethingElse();
}
}
Is it possible somehow, except the way that I pass argument Interface other to C's constructor and store to class property..?
A class cannot extend from its type parameter.
Use composition instead of inheritance:
public class C<T extends Interface> {
private final T foo;
public C(T foo){
this.foo = foo;
}
public void doSomethingElse() {
foo.doSomething();
}
public static void main(String[] args) {
C<?> c;
if(isSomethingLoaded) {
c = new C<>(new A());
} else {
c = new C<>(new B());
}
c.doSomethingElse();
}
}
You might even not need the type parameter here, but just use the interface type as argument/ member type.
I think it's situations like this which show why we have the rule of favouring composition over inheritance. Consider this solution using composition:
public class Test {
public interface Interface {
void doSomething();
}
public static class A implements Interface {
#Override
public void doSomething() {
System.out.println("Doing A");
}
}
public static class B implements Interface {
#Override
public void doSomething() {
System.out.println("Doing B");
}
}
public static class C implements Interface {
private Interface composedWith;
public C(Interface i) {
this.composedWith = i;
}
#Override
public void doSomething() {
this.composedWith.doSomething();
}
}
public static void main(String[] args) {
C c;
if(isSomethingLoaded) {
c = new C(new A());
} else {
c = new C(new B());
}
c.doSomething();
}
}
Personally, I feel this is a clearer and move flexible way of achieving what you are trying to do.

How to call parent method of multiple nested inner class

I want to call A.f() from B.f(), but both are inner classes, if I write the traditional way, it does not compiles.
Any easy way without a temporary variable like the A _this in the code?
class MyClass {
[...]
class A {
public void f(){System.out.println("A.f");};
public void g(){System.out.println("A.g");};
}
class B {
public void f(){System.out.println("B.f");};
}
public A a() {
return new A() {
public void g() {
// I want to avoid this step
final A _this = this;
new B() {
public void f() {
System.out.println("foo");
// this works
_this.f();
// but this does not compile
A.this.f();
}
}.f();
}
};
}
[...]
}
You need to surround the code in brackets properly and then A.this.f() compiles fine E.g.
class A {
public void f() {
System.out.println("A.f");
}
public void g() {
System.out.println("A.g");
}
public A a() {
return new A() {
public void g() {
=
new B() {
public void f() {
System.out.println("foo");
A.this.f();
}
}.f();
}
};
}
public static void main(String[] args) {
new A().a().g();
}
}
class B {
public void f() {
System.out.println("B.f");
}
}
Updated : You can replace _this.f(); with new MyClass().new A().f(); but it will result in creation of new Object.

Force the execution of a method in a class

I'm using Java and I want to call the method f2 in class A from the class B. Is it possible to do this?
public class A{
private B b = new B();
public void f1(){
b.f3();
}
public void f2(){
// do something;
}
}
public class B{
public void f3(){
// Call f2 of class A from here.
}
}
You need an instance of A in class B and invoke f2 on that instance. For example, you could instantiate one inside the body of f3:
public class B {
public void f3() {
A a = new A();
a.f2();
}
}
Another way would be for f3 to receive an instance of A:
public class B {
public void f3(A a) {
a.f2();
}
}
And yet another way, you could have B instantiate one:
public class B {
private final A a;
public B() { this.a = new A(); }
public void f3() {
this.a.f2();
}
}
And lastly, B could receive one in it's constructor:
public class B {
private final A a;
public B(A a) { this.a = a; }
public void f3() {
this.a.f2();
}
}
The point being that if you want to invoke an instance method on a class you must have an instance of that class in your hand.
Finally, I notice that you have A.f1 invoking B.f3 and from there you want to invoke A.f2. So, it looks like your best option here is the second option above. That is:
public class A {
private final B = new B();
public void f1() { this.b.f3(this); }
public void f2() { /* do something */ }
}
public class B {
public void f3(A a) { a.f2(); }
}
The key here is that we are passing an instance of A to B.f3. The way that we achieve that is by passing the this reference, which is a reference to the currently executing instance. In A.f1, that would be the instance of A that is currently executing.
You need an instance of class A to do this.
public class A{
private B b = new B();
public void f1(){
b.f3(this);
}
public void f2(){
// do smthing;
}
}
public class B{
public void f3(A a){
a.f2(); // Call f2 of class A from here.
}
}
This type of code structure is usually more confusing than useful. I suggest instead doing this.
public class A{
private B b = new B();
public void f1(){
WhatAf2Needs w = b.f3();
f2(w);
}
public void f2(WhatAf2Needs w){
// do smthing;
}
}
public class B{
public WhatAf2Needs f3(A a){
return WhatAf2Needs;
}
}
If you want to call a method of the thing that called you, you have to have the caller pass itself in using the this keyword. In code, it would be:
public class A{
private B b = new B();
public void f1(){
b.f3(this);
}
public void f2(){
// do smthing;
}
}
public class B{
public void f3(A caller){
caller.f2();
}
}
You would have to instantiate class A in class B, given the way it's currently written, to make any method calls on it.
You can also declare f2 static and call it like A.f2(). This type of things depend a lot on the design of your classes though. The other answers here are very valid too.
public class A{
private B b = new B();
public void f1(){
b.f3();
}
public static void f2(){
// do smthing;
}
}
public class B{
public void f3(){
A.f2();
}
}

Categories