1

How can I write code below in java version?

I have read similar questions, but they are confusing, they answered that java didn't have delegate feature like c# had, in other hand they answered with their delegate implementation in java, but nothing is similar with my condition. I really hope it's clear on this question. I have been getting stuck since a week

    class Action
    {
        public delegate void ActionDelegate();
        public static ActionDelegate OnAction;

        public void DoAction()
        {
            Console.WriteLine("Action A");
            if (!ReferenceEquals(OnAction, null))
                OnAction();
        }
    }
    class TaskA
    {
        public TaskA()
        {
            Action.OnAction += DoTaskA;
        }
        private void DoTaskA()
        {
            Console.WriteLine("Do Task A");
        }

    }
    class TaskB
    {
        public TaskB()
        {
            Action.OnAction += DoTaskB;
        }
        private void DoTaskB()
        {
            Console.WriteLine("Do Task B");
        }
    }
    class Program
    {
        static void Main(string[] args)
        {
            TaskA taskA = new TaskA();
            TaskB task = new TaskB();
            Action action = new Action();
            action.DoAction();
        }
    }

Output:

Action A
Do Task A
Do Task B
Press any keys to continue...
llinvokerl
  • 965
  • 9
  • 25
J.Smile
  • 41
  • 5
  • 1
    Java uses a single-method interface for this concept. You may optionally apply [`@FunctionalInterface`](https://docs.oracle.com/javase/8/docs/api/java/lang/FunctionalInterface.html) to such an interface. – chrylis -cautiouslyoptimistic- Jan 06 '20 at 03:04
  • Could you give an example about how do you communicate between classes as code below did?, when Action A is called than Task A and Task B is called using the concept since i am newbie on java, what i understand from[@FunctionalInterface](https://docs.oracle.com/javase/8/docs/api/java/lang/FunctionalInterface.html) is only to ensure that the functional interface can’t have more than one abstract method. – J.Smile Jan 06 '20 at 03:16

2 Answers2

0

something similar in java will be to use an interface

you can get the following results

Action A
Do Task A
Do Task B

with the codes below.

import java.util.ArrayList;
public class HelloWorld{

     public static void main(String []args){ 

            TaskA taskA = new TaskA();
            TaskB task = new TaskB();
            Action action = new Action();
            action.doAction();
     }
}

interface ActionDelegate {
    void doAction();
}

class Action{

    static public ArrayList<ActionDelegate> onAction = new ArrayList<>();
    public void doAction(){
        System.out.println("Action A");
        for(ActionDelegate ad: onAction){
            ad.doAction();
        }
    }
}
class TaskA implements ActionDelegate{

    TaskA(){
        Action.onAction.add(this);
    }
    public void doAction(){ 
            System.out.println("Do Task A");
    }

}

class TaskB implements ActionDelegate{

    TaskB(){
        Action.onAction.add(this);
    }
    public void doAction(){ 
            System.out.println("Do Task B");
    }

}
Angel Koh
  • 11,377
  • 7
  • 59
  • 84
0

With the project safety-mirror on your classpath your get library support for delegates and events.

<dependency>
    <groupId>com.github.hervian</groupId>
    <artifactId>safety-mirror</artifactId>
    <version>3.0.0</version>
</dependency>

Here's a snippet from the project's README:

Cheat sheet of features

  • Fun and friends: No more functional interfaces:
    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);
      }  
      foo(System.out::println);   //This signature match the the Fun defined by method Foo. If it did not, the compiler would emit an error.  
    

    It is all type safe: you will get compile time errors if the Method Reference's signature does not match what is defined by the Fun subclass.

      Method m1 = Fun.toMethod(String::isEmpty)
      Method m2 = Fun.<String>toMethod(Class::forName)); // to get overloaded method you must specify parameters in generics  
    
      assertEquals("isEmpty", Fun.getName(String::isEmpty)); //use Fun's static getName method to get the method name. The Method objects returned from toMethod will not return the correct String.
    
  • Delegates in Java!

      Delegate.With1Param<String, String> greetingsDelegate = new Delegate.With1Param<>();
      greetingsDelegate.add(str -> "Hello " + str);
      greetingsDelegate.add(str -> "Goodbye " + str);
    
      DelegateInvocationResult<String> invocationResult = greetingsDelegate.invokeAndAggregateExceptions("Sir");
    
      invocationResult.getFunctionInvocationResults().forEach(funInvRes -> System.out.println(funInvRes.getResult()));
      //prints: "Hello sir" and "Goodbye Sir"
    
  • Events

      //Create a private Delegate. Make sure it is private so only *you* can invoke it.
      private static Delegate.With0Params<String> trimDelegate = new Delegate.With0Params<>();
    
      //Create a public Event using the delegate you just created.
      public static Event.With0Params<String> trimEvent= new Event.With0Params<>(trimDelegate);
    
  • Type safe method creation

      Method m1 = Fun.toMethod(Thread::isAlive)  // Get final method
      Method m2 = Fun.toMethod(String::isEmpty); // Get method from final class
      Method m3 = Fun.toMethod(BufferedReader::readLine); // Get method that throws checked exception
      Method m4 = Fun.<String, Class[]>toMethod(getClass()::getDeclaredMethod); //to get vararg method you must specify parameters in generics
      Method m5 = Fun.<String>toMethod(Class::forName); // to get overloaded method you must specify parameters in generics
      Method m6 = Fun.toMethod(this::toString); //Works with inherited methods
    

Disclaimer: I am the author of the project.

Hervian
  • 1,074
  • 1
  • 12
  • 18