Po pierwsze - spokojnie :D
Zmienna typu interfejsu moze przechowywać rozne obiekty klas implementujacych ten interfejs. To czesc polimorfizmu. Podstawy OOP.
Rola interfejsu to wyrazenie pewnego kontraktu. Interfejs to zbior metod publicznych, których implementacji wymagamy od klas implementujacych interfejs.
Pisząc funkcje ktora przyjmuje jakis interfejs jako argument mowimy, ze wymagamy od obiektow przekazywanych aby mialy zaimplementowane dane metody.
Gdybys typ argumentu byl konkretną klasa mógłbyś przeslac tylko obiekty tej klasy i jej pochodne. Przyklad:
void dodaj5(ArrayList<Integer> list){
list.add(5);
}
Wymagamy arraylisty a wykorzystujemy jedynie fakt ze do tej listy można dodac integer, wiec nic nie stoi na przeszkodzie zeby podac tam inna liste np LiknedList, wiec zmieniamy typ na interfejs:
List<Integer>
Ale moment przeciez do kazdej kolekcji intow da sie dodac 5, wiec czemu sie ograniczac, moze kiedys będziemy chcieieli dodać 5 do HashSet'u
void dodaj5(Collection<Integer> collection){
collection.add(5);
}
To samo tyczy sie innych klas. Od walidatora czegos wymagamy jedynie zeby potrafil zwalidowac to cos czyli zeby mial metode:
bool isValid(Cos cos);
To wymaganie wyrazamy w postaci interfejsu.