Solution 1:

why cant any aggreagtion of objects just implement Iterator interface and imply that it is Iterable

An iterator has state. It has to know what items the iterator has already returned, which items have not, and which item will be returned next.

If a collection was iterator itself, and the enhanced for loop worked on iterators, you would not be able iterate on it twice like this:

for (Employee employee: employeeCollection) {
    // do something
}
for (Employee employee: employeeCollection) {
    // do something else
}

When the first loop completes, that means you have reached the end of the iteration. Therefore the second loop can not iterate on any more items.

You could argue that the start of the loop could somehow implicitly "reset" the iterator back to the start. There is no way to reset an iterator, but that wouldn't solve the problem anyway. How would nested iteration work, let's say you are looking for pair of employees that have the same birthday?

for (Employee employee1: employeeCollection) {
    for (Employee employee2: employeeCollection) {
        // do something
    }
}

If the inner for-loop and outer for-loop share the iterator state, there is no way this algorithm can produce all pairs of employees.

You really need there to be a way to create a fresh iterator that's indepedent of other iterators that may exist. That is what the Iterable interface gives you.

Solution 2:

I could think of one reason also pointed out in the commentss. First of all, if you implement Iterable and override the forEach() method, then you can iterate through data structures like this:

for(int i : myDataStructure) {
    System.out.println(i);
}

If implemented correctly, it should print all the elements in your data structure. For each loops are easier than regular for loops in the sense that different data structures have different ways of iterating. For example with LinkedList if you use a for loop to iterate it will take a longer time since you always start from the head and go to the node at that index every single time. With for-each loops, it saves space and time depending on the data structure.