# Why Interfaces? Suppose you have a collection of students based on the following class ```java package studentchooser; /** * * @author aballantyne */ public class Student {     private String forename;     private String surname;     private int age;     /**     * @return the forename     */     Student(String forename, String surname, int age){         this.forename = forename;         this.surname = surname;         this.age = age;     }     public String print(){         return this.forename + " " + this.surname + ", " + this.age;     }     public String getForename() {         return forename;     }     /**     * @param forename the forename to set     */     public void setForename(String forename) {         this.forename = forename;     }     /**     * @return the surname     */     public String getSurname() {         return surname;     }     /**     * @param surname the surname to set     */     public void setSurname(String surname) {         this.surname = surname;     }     /**     * @return the age     */     public int getAge() {         return age;     }     /**     * @param age the age to set     */     public void setAge(int age) {         this.age = age;     } } ``` You want to print out the students according to certain criteria, for example those under 16 or those with the surname Bloggs. One possible solution is shown below # "Bad" Solution ```java public class StudentChooser {     /**     * @param args the command line arguments     */     public static void main(String[] args) { // TODO code application logic here List<Student> students = Arrays.asList(     new Student("Joe", "Bloggs", 17),     new Student("Emily", "Bronte", 15),     new Student("Mo","Farah",11),     new Student("Jenny", "Bloggs", 15)    ); printAll(students); printUnder16(students);     }     public static void printAll(List<Student> students)     { for (Student student: students) {     System.out.println(student.toString()); }     }     public static void printUnder16(List<Student> students)     { for (Student student: students) {     if (student.getAge()<16) System.out.println(student.toString()); }     } } ``` You can see there is a lot of duplication here. You could imagine having to write a number of methods printSurnameBloggs(), printUnder 21() etc. We need a way to abstract out the common code. Java provides such way with interfaces. # Better Solution with Interfaces ![](https://yuml.me/c0210c8e.png) ```java YUML: https://yuml.me/diagram/plain/class/draw [<<Choice>>]^-.-[StudentChooser] ``` * Notice there is now an interface called Choice added. The interface has one method test() to be overriden * Notice the StudentChooser class has two methods, main() and printChoice() * printChoice()  takes an additional parameter defined according to the Choice interface. We use this "choice" to determine what we are going to filter. ```java package studentchooser; import java.util.Arrays; import java.util.List; interface Choice{     boolean test(Student s); } public class StudentChooser  {     /**     * @param args the command line arguments     */     public static void main(String[] args) { // TODO code application logic here List<Student> students = Arrays.asList(     new Student("Joe", "Bloggs", 17),     new Student("Emily", "Bronte", 15),     new Student("Mo","Farah",11),     new Student("Jenny", "Bloggs", 15)    ); printChoice(students, new Choice() {     @Override     public boolean test(Student s) { return (s.getAge() <16);     } }); printChoice(students, new Choice() {     @Override     public boolean test(Student s) { return (s.getSurname().equals("Bloggs"));     } });     }     public static void printChoice(List<Student> students, Choice choice)     { for (Student student: students) {     if(choice.test(student)) System.out.println(student.print()); }     }  } ``` # Exercise 1. Add a statement to the above code to print out all the people aged 15 2. Add a field to the student class to record gender. 3. Add a statement to the code to print out all students with gender = "m" 4. Add a statement to the code to print out all students under 16 with gender = "f" # Lambda Expressions * You might find your IDE suggests changing your code to include Lambda expressions.  You can learn more about them here.