-1

Interface

public interface InterfaceOne {
    void start();
    void stop();
}

Main Class

public class MainProg {
    public static void main(String [] args){
        new ServiceA().start();
    }
}

ServiceA

import java.util.ArrayList;
import java.util.List;

public class ServiceA implements InterfaceOne{
    private final List<ServiceB> worker = new ArrayList<>();
    public ServiceA(){
        for(int i = 0; i < 2; i++){
            worker.add(new ServiceB(2));
        }
    }

    @Override
    public void start() {
        worker.forEach(InterfaceOne::start);
    }

    @Override
    public void stop() {
        worker.forEach(InterfaceOne::stop);
    }
}

ServiceB

public class ServiceB extends ServiceC{
    int count;
    protected ServiceB(int num){
        this.count = num;
    }
}

ServiceC

public class ServiceC implements InterfaceOne{
    @Override
    public void start() {
        System.out.println("Starting..");
    }

    @Override
    public void stop() {
        System.out.println("Stopping..");
    }
}

Here from the main class, I am calling a method of ServiceA that internally calls to the method of serviceB using the method reference operator. ServiceA Can be also written like below where instead of using the method reference operator i can use lambda function

import java.util.ArrayList;
import java.util.List;

public class ServiceA implements InterfaceOne{
    private final List<ServiceB> worker = new ArrayList<>();
    public ServiceA(){
        for(int i = 0; i < 2; i++){
            worker.add(new ServiceB(2));
        }
    }

    @Override
    public void start() {
        worker.forEach(obj -> obj.start());
    }

    @Override
    public void stop() {
        worker.forEach(obj -> obj.stop());
    }
}

Here I am aware of how this program is working using lambda function, but want to understand how it is working with the method reference operator

worker.forEach(InterfaceOne::start);

The output of this program is

Starting..
Starting..
Programming-Lover
  • 1,177
  • 10
  • 14
  • Inside your ServiceA you are calling the methods on your `private final List worker` list, which as you can see contains Objects of type `ServiceB` and those calls on `ServiceB` are what are generating the output. That you for some reason decided to have `ServiceB extends ServiceC` probably just added to your confusion. ( If you name classes A, B, and C you usually expect those names to mean that B extends A and C extends B, not what you decided to do) – OH GOD SPIDERS Jun 09 '22 at 15:51
  • Thanks for the reply can you please explain this line: worker.forEach(InterfaceOne::start); here I am calling InterfaceOne::start – Programming-Lover Jun 09 '22 at 15:56
  • That line iterates over all objects in the `workers` list and calls the method `start` on each one. This was btw already explained in the answer you got below. – OH GOD SPIDERS Jun 09 '22 at 15:57
  • What output did you expect? Why? – Sotirios Delimanolis Jun 09 '22 at 16:04
  • ```worker.forEach(obj -> obj.start());``` and ```worker.forEach(InterfaceOne::start);``` above two lines creates same output, here i want to understand more about ```worker.forEach(InterfaceOne::start);``` – Programming-Lover Jun 09 '22 at 16:14
  • I don't understand. You don't mention a lambda expression in your post. Is this a new question, trying to compare those two? – Sotirios Delimanolis Jun 09 '22 at 16:15
  • My Bad, Should I update the question? Actually, that's the confusion for me how ```InterfaceOne::start```is being interpreted – Programming-Lover Jun 09 '22 at 16:23
  • Yes please, edit to clarify the questions in the comments. – Sotirios Delimanolis Jun 09 '22 at 16:25

1 Answers1

1

You wrote:

worker.forEach(InterfaceOne::start);

This calls the start method for every element of the worker list. It does not matter if it's called in the scope of a method of ServiceA, the elements of the worker list are ServiceB's, which inherit the start method of ServiceC.

GeertPt
  • 16,398
  • 2
  • 37
  • 61