Chapter:Interfaces - Implementing an interface

From Juneday education
Jump to: navigation, search

Meta information about this chapter

Expand using link to the right to see the full content.

Introduction

This is what we tell our students:

An interface specifies a behavior by defining methods. Regardless of what your class is an abstraction of (e g a Passport) it can implement a behavior such as being comparable with other objects. In order for your class’ objects to be considered “Comparable”, there is an interface in the Java API called java.lang.Comparable, which your class should implement, For this, your class needs to implement the methods specified in the interface.

This topic is about teaching them how to do just that, how to implement an interface.

Prepare

Read up on interfaces, watch the video lectures (so that you can answer the students' questions), do the exercises (so that you can supervise the students during exercise sessions).

Expect this lecture to take around 45 minutes, just to go through the slides. Speed up, if you want to be interactive with the students (as usual, it helps to demand that they watch the video in advance).

Purpose

The student shall get a feeling of what it means to implement an interface. For instance, we'll try to purvey this by using Comparable as an example.

By implementing the java.lang.Comparable interface, the student shall recognize that a list (or array) of references to instances of her own class, can be sorted by methods written in many Java years ago, without any prior knowledge about the student’s own class. This is possible, due to the fact that the designers of the Java API decided that interfaces in general was a good idea, and in this case, the java.lang.Comparable interface was in particular a good idea. This interface let's any class designer (like our students) enhance their classes so that their instances become comparable, and thus collections of said instances become sortable.

Goal

On the completion of this lecture/topic, the student shall:

  • know what it means to implement an interface syntactically and semantically
  • know how implementing an interface differs from inheriting a class (syntactically and semantically)
  • have seen, used and understood how interfaces such as Comparable and Comparator can be used to compare objects which in turn can be * used by some of the sort methods shipped with Java (or for that matter, by implementations of trees, such as TreeSet, TreeMap etc)

Instructions to the teacher

Common problems

Students sometimes initially fail to understand how Arrays.sort can sort an array of object references of a class the students have written themselves. By explaining this many times and possibly, adding a printout statement in the compareTo method (in the case of Comparable) the student will come closer and closer to an understanding. Understanding what it means to implement an interface is crucial before we proceed with writing our own interfaces, so spend time with your students on this topic.

Note: be careful when adding a printout statement to the compareTo method, since students also struggle with understanding the difference between a method returning a value (like compareTo is), and printing something out on stdout...

We sometimes use a taxi service as an example, when teaching interfaces. Cars and other vehicles can serve as a taxi. When we call for a taxi, we don’t care so much about what kind of car the taxi is, or even if it is a car. It could be a rickshaw, a bicycle, skateboard or whatever, as long as the taxi can take us to the place we want. We expect the taxi to respond to the message “Drive to location X”, etc. In Java, the class implementing the Taxi interface would then contain a method like the below:

  void driveTo(Location location);

Anyone who wants to offer taxi services need to be able to take a passenger to the requested location. Same with classes who we want to be a taxi, they need to implement the taxi interface (and the method driveTo).

Interfaces: Implementing an interface

SomeClass implements Comparable<SomeClass>

If we want to create a class, SomeClass, whose objects are comparable to each other, we use the keyword implements followed by Comparable<SomeClass>:

public class SomeClass implements Comparable<SomeClass>{
  // we now need to implement the compareTo(SomeClass o) method!
}

How would we know how to implement the compareTo() method, and whether we have to implement some more methods? Easy! We have to read the documentation for Comparable. It lists the abstract methods we need to implement (in this case, only one, luckily for us!) and what these methods should do. If we read about this only method, compareTo(), we'll see that it should return an int representing the result of the comparison. A negative value represents that the object is less than the other object (given as argument), a value of 0 means they are considered equal and a positive value means that the object is greater than the object given as argument.

Let's exemplify this using Strings (which we know are comparable, because reading the documentation for String tells us that String implements the Comparable<String> interface, and thus has a functioning implementation of compareTo(String o) ).

    String s = "Ape";
    System.out.println(s.compareTo("Zebra"));  // -25
    System.out.println(s.compareTo("Ape"));    //   0
    System.out.println(s.compareTo("Abraham"));//  14

The comments show what would be printed if we ran this snippet of code (in a main method for instance). A negative number for the comparison of "Ape" to "Zebra" (because "Ape" is considered less than "Zebra" lexicographically), a 0 for the comparison of "Ape" to "Ape" (because they are equal) and a positive number for the comparison of "Ape" to "Abraham" (because lexicographically, "Ape" is greater than "Abraham" because of the second character).

So, in order to implement the Comparable<SomeClass> interface, we must write an instance method compareTo(SomeClass o) where we compare this object with the object referred to by o which we get as a parameter. Then we must return an int representing the result of the comparison - if this object and o are equal (in terms of comparisons) we should return 0. If this object is less than the object referred to by o, we should return a negative number. Otherwise we should return a positive number.

What the negative and positive numbers are doesn't matter. It is just the sign which is important.

Now, we can actually ask some method to sort an array (or list) of SomeClass references. The sorting method will use the fact that SomeClass objects are comparable, and call the compareTo method on each one of them in order to find out how to sort the array (or list). One such method we could use is the static method sort() in the java.util.Arrays class, which exists in a version which accepts an array reference. Note that the sort method would crash if we sent it an array whose elements are not Comparable.

What if we want to sort an array whose elements are not comparable? Maybe the elements are of some class which we cannot change into being Comparable (because we don't have access to the source code for instance). Don't worry! There is another version of sort in Arrays (and the similar class for lists, Lists) which take two arguments. This version takes as the first argument the reference to the array to be sorted, and as the second argument an object which indeed can compare two objects of the array element type.

MemberComparator implements Comparator<SomeClass>

How have they implemented this? Well, again with the help of interfaces (admit that you start to like interfaces!). The comparator object is of type Comparator which is an interface in the java.util package. The Comparator<T> interface has a method which you need to implement in order to claim that some class is a Comparator: public int compare(T first, T second).

As you see, a comparator object can compare two objects of some type. This means that we can retrofit comparability to a class using a comparator helper object.

Let's say that we have a class Member which is not Comparable. But we want to be able to sort an array of Member references. Now, we can create a Comparator by writing a new class MemberComparator implements Comparator<Member>. This class must implement the method int compare(Member first, Member second) and return an int as if we compared first to second.

Again, if first is less than second, we should return a negative value. If they are equal we should return 0 and otherwise return a positive number. Using this class, we can create a MemberComparator object and use that as the second argument to the version of sort() which took two arguments.

public class MemberComparator implements java.util.Comparator<Member>{
  @Override
  public int compare(Member first, Member other){
    return... // code which produces an int according to the rules...
  }
}

The call to sort would then be something like Arrays.sort(memberArray, new MemberComparator());

Chapters on the topic of Interfaces

You can check your progress on this chapter using this list:

Videos

English videos

Swedish videos

Links

Further reading

Where to go next

Next page has exercises for this chapter: Interfaces - Implementing an interface - Exercises

« PreviousBook TOCNext »