CSCD 211 › lessons

Prerequisite: an interface is a promise a type makes

This is the rung under everything you do in Week 1. In 210 you wrote classes and you called methods on them. You never had to name a capability on its own, apart from any one class. This lesson does exactly that, and the thing you build is the interface. By the end the word Comparable you meet on Tuesday will not be a new keyword to memorize. It will be the obvious name for a promise you already saw the need for.

Quick check before you climb (retrieval first)

Answer from memory before reading on. No stakes; pulling 210 back up now is what makes the new idea stick.

Check yourself. In 210 you wrote a method and then called it: book.getTitle(). The call works because the Book class has a method with that exact name and signature. Say, in one sentence, what the caller is relying on when it writes book.getTitle().

The point

By the end you can explain why a sort does not need to know an object's class, only one capability it has; you can read implements Comparable as a type signing a named promise and supplying the method body; and you can say why one sort, written before your class existed, can order your objects the moment your type keeps that promise. One climb, each rung a click.

The problem (sit with this before reading on)

You wrote a method last week that sorts an array of Book by title. It works. Today you have an array of Course, and you want the same sort. The bodies would be almost identical, so copying the whole method and changing Book to Course feels wrong, and it is. Look at what the sort actually touches:

for (int i = 0; i < a.length - 1; i++) {
    if (a[i].comesAfter(a[i + 1])) {
        swap(a, i, i + 1);
    }
}

The sort never reads a title, a price, a course code, or a credit count. The only thing it ever asks of a Book, or a Course, is one question: given these two, which one comes first. Everything else about the class is invisible to it.

Check yourself. The sort above only ever calls comesAfter on its elements. Without knowing the fix yet, name the one thing the sort actually needs from any type it is asked to sort.

Rung 1: the sort needs a capability, not a class

A sort that says Book[] in its signature can only ever sort books, even though it never uses anything that makes a book a book. That is the waste. The honest description of what the sort can handle is not a class at all. It is a capability: "anything that can tell me which of two of them comes first." A Book has that capability. So does a Course. So does a Section you have not written yet. The class is the wrong unit to ask for, because the orders you want to sort share a capability, not a family.

So the question becomes mechanical: how do you write down a capability in Java, as a thing the sort can demand, without naming any one class that has it. Java has one construct built for exactly this, and it is the interface.

Collectible insight. Code should ask for the smallest capability it needs, not the biggest class that happens to have it. A sort needs "can be compared," never "is a Book."

Check yourself. Two classes, Book and Course, are unrelated; neither is built from the other. They share no fields. Yet one sort should handle both. In one sentence, what do they have in common that the sort cares about?

Rung 2: an interface is a named promise with no body

An interface is a name for a capability and the exact methods that capability requires. In its most common form it carries no working code, only the signatures a type must fill in. Modern Java lets an interface include a few ready-made methods, which you meet later in the term; Comparable and Comparator are the pure kind, just a signature. Here is the one Java already ships, simplified to its heart:

public interface Comparable<T> {
    int compareTo(T other);
}

Read it literally. It declares a type named Comparable. It promises one method, compareTo, that takes another object and returns an int. It supplies no body, because an interface does not say how any particular type compares; it only says that a type claiming this capability must provide that method. The interface is the promise; the class that signs it provides the proof.

A class signs the promise with implements, and then it must keep it by writing the method:

public class Course implements Comparable<Course> {
    public int compareTo(Course other) {
        return Integer.compare(this.code, other.code);
    }
}

implements Comparable<Course> is Course raising its hand and saying "I can answer which of two courses comes first." The compiler now refuses to build Course unless that method is present, so the promise cannot be claimed and then quietly broken. The order you write inside is the one from the previous rung: a sign, never a subtraction, built with Integer.compare. The interface decided the method must exist; you decided what the order is.

Collectible insight. An interface is a named set of method signatures: a promise a type can sign with implements and must keep by supplying the bodies. A pure one like Comparable carries no state and no method bodies, only the signatures a type fills in.

Check yourself. A class writes implements Comparable<Course> but never declares a compareTo method. Predict what happens, and say which line is at fault.

Rung 3: write the code once, against the promise, and every keeper of the promise works

Here is the payoff, and it is the reason interfaces exist at all. A sort can name the interface in its signature instead of a class:

static void sort(Comparable[] items) {
    // ... only ever calls items[i].compareTo(items[j])
}

This method was written once. It can be compiled before Course exists, before you were enrolled. It accepts any array whose elements implement Comparable, and it orders them by calling the one method the promise guarantees. The day you write class Course implements Comparable<Course>, your courses become sortable by this exact code, with not one line of the sort changed. This is what Java's real Collections.sort and Arrays.sort do, and it is why they can sort a type the library authors never heard of.

That is the whole bargain of an interface. The code that uses the capability and the code that provides the capability are written by different people at different times and never have to meet. They agree only on the promise: the method name, what goes in, what comes out. A new type joins the moment it keeps that promise, and nothing already written has to change to admit it. You will hear this called programming to an interface, and the property it buys, adding new types without reopening old code, is the design idea the whole course returns to.

Collectible insight. Code written against an interface runs for every type that keeps the promise, including types written later. One sort, every comparable thing, no edit to the sort.

Check yourself. A library author ships sort(Comparable[] items) in 2019. In 2026 you write a brand-new class that implements Comparable. In one sentence, why can the 2019 sort order your 2026 objects without being recompiled or changed?

Rung 4: a type can keep many promises, and a promise can be handed in from outside

Two more facts and the picture is complete for Tuesday.

First, a class can sign more than one promise. A Course can be Comparable and also, in Week 6, Schedulable and Conflictable, because keeping several unrelated promises is normal and each is a separate small capability. This is different from a class being built from a parent class, which you meet later; an interface is a capability a type claims, not a family it belongs to.

Second, Comparable is the order a type carries built in, its one natural order. But often you want a different order for the same type, by title instead of by code, and you do not own the class to add an order to it, or you need several orders at once. For that, Java has a second interface, Comparator, that holds the order outside the type:

public interface Comparator<T> {
    int compare(T a, T b);
}

A Comparator is the same idea as Comparable, a one-method promise about ordering, with one difference: it is a separate object you hand to the sort from outside, rather than a method baked into the type. Tuesday splits exactly on this seam. The first block is the built-in promise a Course carries, Comparable. The second block is the handed-in promise you supply from outside, Comparator. Both are interfaces; both are one method; you already know what that means.

Collectible insight. Comparable is the one order a type carries inside itself; Comparator is an order handed in from outside. Both are one-method interfaces, so a type can be sortable by its own rule and by any number of outside rules at once.

Check yourself (competency close). Finish in your own words: "An interface is a named ___ with no . A class signs it with ___ and keeps it by . Code written against the interface works for , because it depends only on the ."

Where to read more (use whichever fits you)

You do not need a book for this; the lesson stands on its own. If you learn better from a text, or want a free option, each resource covers interfaces from its own angle.

What you collected

Walk into Tuesday with the interface already in hand, so implements Comparable reads as a type signing a promise you understand, and the split between the built-in order and the handed-in one is a seam you saw coming. The order itself, why it is a sign and never a subtraction, is the rung just below this one in order is a sign.