Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Java How does this interface code actually work?

Tags:

java

I've put together the code below using ideas giving to me by fellow members and then changing a couple of the containers. For the life of me i cant really get my head around some of this. The reason for the code is that i wished to pass a function as a parameter. The part of code i especially don't understand is:

doFunc(numbers, new IFunction() { 
    public void execute(Object o) { 
       Integer anInt = (Integer) o; 
       anInt++;
       System.out.println(anInt);
    } 
}); 

I understand to some extent that we're using an interface to represent a function using an object (i think?). This is the full code:

public static void main(String[] args) {
    Integer[] strArray = new Integer[]{1,2,3,4,5};

    List numbers = Arrays.asList(strArray);
    doFunc(numbers, new IFunction() { 
        public void execute(Object o) { 
           Integer anInt = (Integer) o; 
           anInt++;
           System.out.println(anInt);
        } 
    }); 
    for(int y =0; y<numbers.size();y++){
        System.out.println(numbers.get(y));
    }
}

public static void doFunc(List c, IFunction f) { 
   for (Object o : c) { 
      f.execute(o); 
   } 
}

public interface IFunction { 
    public void execute(Object o); 
} 

I guess i just need someone to go a little slower explaining it. Thanks for bearing with me.

like image 538
Jason Avatar asked Sep 18 '26 00:09

Jason


2 Answers

That's an anonymous inner class. You could do as good as follows:

public static void main(String[] args) {
    Integer[] strArray = new Integer[]{1,2,3,4,5};

    List numbers = Arrays.asList(strArray);
    doFunc(numbers, new ConcreteFunction()); 
    for(int y =0; y<numbers.size();y++){
        System.out.println(numbers.get(y));
    }
}

public static void doFunc(List c, IFunction f) { 
   for (Object o : c) { 
      f.execute(o); 
   } 
}

public interface IFunction { 
    public void execute(Object o); 
} 

public class ConcreteFunction implements IFunction {
    public void execute(Object o) { 
       Integer anInt = (Integer) o; 
       anInt++;
       System.out.println(anInt);
    } 
}

The difference is that a concrete class is reuseable while an anonymous inner class is not.

See also:

  • Java tutorial - Inner classes
like image 190
BalusC Avatar answered Sep 20 '26 12:09

BalusC


The main concept here is that since the second object you're passing to doFunc is anonymous, you don't need to instantiate an object here - just the interface. Here's what each part of the code is saying:

public interface IFunction { 
    public void execute(Object o); 
}

This says that any object which implements the interface IFunction has one method, execute, which it runs on another Object.

public static void doFunc(List c, IFunction f) { 
   for (Object o : c) { 
      f.execute(o); 
   } 
}

This function takes a List c and any Object which implements IFunction, then runs the execute method - guaranteed to be in the second object by the IFunction interface - over all the objects in c.

    doFunc(numbers, new IFunction() { 
        public void execute(Object o) { 
           Integer anInt = (Integer) o; 
           anInt++;
           System.out.println(anInt);
        } 
    });

This snippet from main takes a list of numbers and creates an anonymous object in-place which implements the IFunction interface. Since it's not any concrete object type, it doesn't need to have any other methods, just execute, which it defines inline.

The end result is that your IFunction object declared inside the call to doFunc is effectively a functor - it's a throwaway object that encapsulates a function, which can be run over a list of objects.

like image 42
Tim Avatar answered Sep 20 '26 14:09

Tim