Hi, I am still learning myself, but I will try and explain it to you.
Coding to an interface you can know in the future you will be able to deal with objects that implement that interface, as they will have at least implemented the method declared. I will try to give an example to explain:
//Here declare a List reference (interface) to an ArrayList
List arrayList = new ArrayList();
In the above code you can see arrayList is a list object, but at compile time it is a List reference so the only methods you can call on arrayList are the List methods that it has overridden as at compile time the compiler doesnt know that this might be an ArrayList object.
If you declare a method that takes as an input parameter a List object then you know that your method will always be able to take a future object that implements List (one that doesnt even exist right now) and your method will always be able to call those List methods.
I guess you need to make a decision about whether doing this is the right thing in your current situation. Sorry I cant explain it better but I expect someone else will answer.
Thought I would just add something about your example above, basically the top example declares the list objects type as the interface, this means ANY object that implements Igroup can be put in this list. In the second example it is not as flexible, basically you are saying ONLY GroupImpl objects can be placed into the list. This maybe what you want.
If you had a setter method for instance, your version would only ever allow people to pass in GroupImpl to set to the list because thats the only object the list can hold, but if you make the method take a type Igroup, and make the list take objects of type Igroup then anyone in future can use your method, all they have to do is implement Igroup. Your code always knows it can call the methods defined in the interface because anything coming in is an IGroup and must have implemented at least those I group methods.
The reason your method cannot work is that you say it returns a type Igroup, so anyone calling it expects to get an Igroup, right? So it wouldnt make sense to give them GroupImpl because they might not even know about it, THEIR reference that they try to assign the object returned from your method might have implemented Igroup but never extended GroupImpl.
If I remember rightly methods that are available to an object are always based on the reference type. Sorry its a bit rambling.