10
$\begingroup$

When teaching Interfaces (in Java, for example), it is common to describe them as a contract. Which means that if a class implements an interface, it has to use the methods in the interface.

As an example, the students are shown the following:

public interface Edible {

    public boolean hasNuts();
    public void eat();
}

and then

public class PeanutbutterSandwich implements Edible {

    //now  we have to implement the methods in Edible
    public boolean hasNuts(){
        return true; //just as an example
    }
    public void eat(){
        if(hasNuts())
            System.out.println("I contain nuts!");
        else
            System.out.println("I don't contain nuts!");
    }
}

The problem with this example is that students don't always see how the interface acts as a contract. How could I explain the analogy in a better way, maybe with a different example that can show this in a better way?

The students are high school level, and are familiar with polymorphism, but not with abstract classes.

$\endgroup$
6
  • 1
    $\begingroup$ At least in this example, consider changing the class Edible to Food. It makes more sense to have the interface name a noun in this context as I see it. $\endgroup$
    – Peter
    Jun 11, 2017 at 7:18
  • 1
    $\begingroup$ @Peter I thought about it but I feared it was too much like a name I'd give an abstract class. But after more thought, i think it's not as confusing as I thought. Btw, it's not a class, but an interface $\endgroup$
    – ItamarG3
    Jun 11, 2017 at 7:20
  • 1
    $\begingroup$ The contract on Eat is I take no data, I return no data, you can call me under any situation, and I promise to do what ever I want (your guess is as good as mine as to what I will do). I.E. there is no contract. They don't see it because it is not there. Do design by contract, that has contracts (pre and post conditions). $\endgroup$ Jul 21, 2017 at 20:19
  • 5
    $\begingroup$ public interface Edible { public boolean isEdible(); I find this a very bad example for students. If a class has the Edible interface, it is therefore edible. Not only should the boolean value be irrelevant, it downright contradicts the meaning of assigning an interface to a class ("it is edible because the interface is assigned, but it's not edible because the boolean says it isn't"). In most (common) cases, the fact that you assign the interface is confirmation that the class is "Fooable". If it isn't Fooable, then it shouldn't have the IFooable interface. [..] $\endgroup$
    – Flater
    Nov 15, 2018 at 13:17
  • 2
    $\begingroup$ [..] It also doesn't make sense to have an eat() method for something that's not edible. You're sullying the clear contract by having that boolean in the middle of it. The boolean (when false) can effectively negate the primary reason for the contract to exist in the first place. $\endgroup$
    – Flater
    Nov 15, 2018 at 13:20

10 Answers 10

8
$\begingroup$

A few things jump out from the official Java documentation:

As far as an example goes, the idea of a Remote as an interface works really well based on this explanation.

Methods form the object's interface with the outside world; the buttons on the front of your television set, for example, are the interface between you and the electrical wiring on the other side of its plastic casing. You press the "power" button to turn the television on and off.

Using topics like design or hardware might be a good direction to go since a discussion of UI could build up into a more abstract understanding of the notion of an interface.

It is important to note that this documentation makes use of the same contract analogy you mention:

Implementing an interface allows a class to become more formal about the behavior it promises to provide. Interfaces form a contract [emphasis added] between the class and the outside world, and this contract is enforced at build time by the compiler.

To implement an interface is to promise, to guarantee, that the class will come through on its end of the bargain and implement everything in the interface. The idea of a contract is already a successful analogy, so I wouldn't try to necessarily reinvent the wheel here lest you introduce more confusion with a different analogy. You could have students use the word promise if contractual language does not hit home for them.

Putting it in the context of friendship and promises being made might make them understand an interface in a better way than legal agreements and contracts. Ultimately, simple, relevant examples that clearly illustrate why interfaces are of value and how they are central to human-computer interaction will probably be of more value than a different, clever analogy.

You may find this since-closed discussion on SO of value.

$\endgroup$
2
  • $\begingroup$ The context of friendship sounds potentially useful. $\endgroup$
    – ItamarG3
    Jun 11, 2017 at 8:27
  • $\begingroup$ I just want to add onto this remote example. I did an assignment for class where students were constructing interfaces/classes for a Samsung-esque company. So they had interfaces like VoiceAssistant that were then only implemented on some of their classes (e.g., smartphone, smart assistant, but not TVs). The students found it very effective! $\endgroup$ Oct 13, 2018 at 21:11
8
$\begingroup$

This answer draws on Java examples.

I start the interface discussion with a mechanical SATA hard drive in my hand. I discuss the interface called SATA and its universality across devices. I expand this with some digital images of SATA on an optical disc drive as well as a solid state hard drive. Some discussion follows regarding the variety of brands and companies but also the assurance of SATA's common functionality that makes it possible for everyone to play nice together and make reliable components that work across so many devices.

The students verbally list some functions of the SATA interface. I prompt them by asking what all these devices are required to do: read data, write data. Depending how long you want to spend on this and how it matches your curriculum, you get more information from them - what parameters might those functions have etc. Talk about data storage or bits and bytes if its relevant, etc.

All the while, I've listed these functions on the board. Finally, when I think we're done brainstorming, I wrap them in curly brackets and label it an interface. Be careful not to attempt an implementation of any of the functions. That doesn't belong in an interface. (Aside, digging into some Java interface source code, I was surprised to learn of the default function introduced in Java 8 - a lot of things surprised me really when I started digging into the Java source.)

This is my hook for the interface lesson. Next, I jump into all the textbook examples like Edible, Animal, or whatever other abstractions you're going to see at this point in a textbook.

Finally, whether the textbook likes it or not, I slap a Comparable vs Comparator (Java) problem on all of them and make them sort some Geometric objects or something. I spend the next 30 minutes walking around helping students comprehend compiler error messages like "Triangle and Rectangle don't implement the Comparable interface" or "Triangle must implement Comparable.compareTo" or something like that.

Inevitably, many questions about how compareTo works or should work come up. I explain -1, 0, 1 for <, ==, > respectively but then I will show them the source code for java.lang.String or wherever that is, and discuss how Comparable strings actually use the difference between ASCII character codes to compare characters. If not GeometricObjects, ask them how they would sort themselves - height? GPA? grade level? Obviously we need a Comparator for each property if multiple different sorts are needed. It may help to demonstrate that Collections.sort(arrayList) of complex objects won't work with Comparability.

When trying to nail the point, "Always program to an interface," my go-to example is the List interface. I say "Because it's easier to maintain later. If you change the interface, the compiler will require you fix all the implementing classes." I instantiate a few, Vector, LinkedList, ArrayList, with only the interface on the left hand side of the instantiation, List = ArrayList, for example. I show them the source code for the List interface in Java but with Oracle's comments removed so it's just a list of functions. I then show them the same set of common functionality across all implementing classes, only now it's listed in the Eclipse intellisense. This point about always program to an interface is apparently only worth mentioning because those who stay with programming will hear it again some day and you've laid almost a foundation. It's not a point I would spend too much time on with high school students. I drop the phrase and expect they'll hear it again if they carry on with software development.

... and right before I think they get it, time demands that we move on to something else. Hopefully some later assignments revisit the interface.

$\endgroup$
1
  • $\begingroup$ Wow! This is a very good answer. Welcome to Computer Science Educators, I hope we'll be hearing more from you. $\endgroup$
    – ItamarG3
    Jul 23, 2017 at 4:54
6
$\begingroup$

I believe that using the term "contract" is hurting more than helping. Most students in that age-range have no personal experience with contracts, so the term is too abstract or remote. Secondly, using contract to "define" the rules for using an interface is likely to lead to a circular definition when you define what a contract is. To increase comprehension for the students it is better to use something they already understand in explaining new concepts.

Using an analogy for how implement in the class declaration relates to the interface you could try using a survey form as an example. A fill-in-the-blank survey has no right or wrong answers, only questions that need an answer, but the answer has to be the right kind. A question about favorite color should not be answered with "scuba diving". If the form has five questions, and only four are answered, it is incomplete and thrown out as unusable, and no credit is given for doing it. In interface declaration is the same way. It lists the methods, their return types and their parameters, but they are blank methods that don't do anything. When the class declaration implements that interface it has to fill in all the blanks and how they are filled in has to match how the interface declared them, the same return type and the same number and type of parameters.

Once they have a grasp on the rules for using interfaces you can use interfaces to explain what a contract is, and how using an interface is part of fulfilling a contract.

$\endgroup$
7
  • $\begingroup$ I like the analogy, but I'm not sure it'll make it clear that implements I'd binding $\endgroup$
    – ItamarG3
    Jun 11, 2017 at 8:59
  • $\begingroup$ First day of the term, use a survey, with the stated rules that any open blanks on the survey is an error: no credit. $\endgroup$ Jun 11, 2017 at 9:01
  • $\begingroup$ So then I could say that the student's answers implements SurveyAnswer and as such should contain answers for each question, and of the fitting type? $\endgroup$
    – ItamarG3
    Jun 11, 2017 at 9:03
  • $\begingroup$ I don't even like the analogy. I believe this is no more of a contract than using strong types (or a rigorous formatting styles) which permits automated checking for consistency. My view (with zero experience of java) is that an interface definition permits the compiler to tell you when you've made incorrect assumptions. There is no mutually beneficial trade as implied by a true contract. $\endgroup$ Jun 11, 2017 at 9:20
  • $\begingroup$ @SeanHoulihane that is not entirely true. There might not be any mutually beneficial trade, but it's not a definition that allows the compiler to know of incorrect assumptions, either. It is a binding construct. But the idea of a contract is useful. I am trying to explain that to the students. $\endgroup$
    – ItamarG3
    Jun 11, 2017 at 13:18
3
$\begingroup$

I have a bit of a quibble here. The only thing enforced by Java when implementing an interface is the structure of the class implementing it. The intent of the interface programmer isn't enforceable. Good names will help express the intent, but not enforce it. Good javadoc comments will convey more of the intent, but again it isn't enforceable. Absent some compiler/runtime enforcement mechanism of pre and post-conditions and invariants it is pretty unlikely that this will change.

Other languages do, of course, provide such a mechanism which leads to design by contract.

However, what we CAN teach our students is to program to the intent of the code we are working with and not just its structure. And that is always true, not just when implementing an interface. So, In my class the interface of the original post here wouldn't be acceptable, coming without clarifying javadoc comments. It is a contract (only) if you treat it as such. But lots of human interactions are similar.

BTW, students writing subclasses (which IMO is too often done poorly) break the intent of the superclass as well as the structure. Among other things, subclassing by adding public features makes Liskov's Substitution Principle impossible to obey. If you need to cast, your code is probably broken. I'll wait for a good question about subclassing in Java-like languages to talk about why that is.

$\endgroup$
3
  • $\begingroup$ java enforces that an implementing class actually implements the method signatures defined in the interface. Anything that implements a specific interface is promising that you can work and use only the parts that are from the interface (Interface objectName = new ImplementingClass()). At compile time, you can use anything that Interface says, but not what ImplementingClass() can do which isn't related to the interface. My point is that I'm not sure I understand why you say that intent is the only thing enforced. $\endgroup$
    – ItamarG3
    Jul 23, 2017 at 11:35
  • $\begingroup$ Declaring variables with the interface type is good style but, unfortunately only style, and that isn't enforced. $\endgroup$
    – Buffy
    Jul 23, 2017 at 12:11
  • $\begingroup$ Domain Specific Languages have a lot of advantages and have existed since long before OOP came about. The biggest advantage, from my point of view, is that I can hand over a lot of 'programming' work to non-programmer domain experts, including ordinary folks. My first goal as a programmer is to make my services no longer required. I used to be quite successful at that. $\endgroup$
    – Scott Rowe
    Oct 17, 2018 at 21:06
2
$\begingroup$

An interface "isn't" a contract. But it embodies a contract. Implicitly if not explicitly.

A simple example is when you go to Kinko's (FedEx), and you click on the end of the opening interface that you agree with the terms of use. In turn, Kinko's agrees to provide you with a bunch of computer services, express or implied, for the money you are paying them.

Other interfaces don't necessarily have a paywall, but they usually have terms and conditions (going both ways), plus the requirement that you provide at least a minimum of ID to use them.

$\endgroup$
4
  • $\begingroup$ interface specifically isn't about the user interface, it's about the object oriented programming interface. $\endgroup$
    – ItamarG3
    Jun 11, 2017 at 13:35
  • $\begingroup$ This analogy works. FedEx ask for payment, a box, and a destination. Whatever is in the box, they'll ship it even if you put perishables in the box (or lithium batteries), and their shipping method isn't appropriate. They don't guarantee the contents arrive unharmed, they just move the box and its contents. Mis-treat an API, and you have a validation problem. $\endgroup$ Jun 11, 2017 at 13:48
  • $\begingroup$ @SeanHoulihane but I am hoping that FedEx would in fact enforce their conditions, because they don't want an entire truckload or plane cargohold of packages to burn up, whether I cared (or perhaps intended that) or not. Caring to protect yourself and your users is the bottom line. $\endgroup$
    – Scott Rowe
    Oct 17, 2018 at 20:39
  • $\begingroup$ @ScottRowe Your desires are irrelevant to the interface. There are implications for misusing the interface, but an interface which includes testing of its inputs is more expensive. Providing an un-validated interface may also be expensive (see GPZ vulnerabilities which use speculation and a cache side-channel) - this is reflected in your risk analysis. $\endgroup$ Oct 18, 2018 at 7:54
2
$\begingroup$

I really enjoy the answer to this question provided on StackOverflow and use it as a basic introduction/discussion point in my CS2 course:

Consider the following situation:

You are in the middle of a large, empty room, when a zombie suddenly attacks you.

You have no weapon.

Luckily, a fellow living human is standing in the doorway of the room.

"Quick!" you shout at him. "Throw me something I can hit the zombie with!"

Now consider: You didn't specify (nor do you care) exactly what your friend will choose to toss; ...But it doesn't matter, as long as:

-It's something that can be tossed (He can't toss you the sofa)

-It's something that you can grab hold of (Let's hope he didn't toss a shuriken)

-It's something you can use to bash the zombie's brains out (That rules out pillows and such)

-It doesn't matter whether you get a baseball bat or a hammer - as long as it implements your three conditions, you're good.

To sum it up:

When you write an interface, you're basically saying: "I need something that..."

$\endgroup$
2
  • $\begingroup$ This is an incredibly simple and very nice answer. Thank you! $\endgroup$
    – ItamarG3
    Oct 14, 2018 at 7:52
  • $\begingroup$ @ItamarG3 It also is fun to see how much your students really have thought about the zombie apocalypse... :) $\endgroup$ Oct 14, 2018 at 18:46
1
$\begingroup$

Java (and most other languages) interfaces are not contracts.

The contract on Eat is:

  • I take no data
  • I return no data
  • you can call me under any situation
  • I will not crash/throw (most languages don't even have this)
  • I will do what ever seem like a good idea to me

I.E. there is no contract. They don't see it because it is not there. Without pre and post conditions, there are no promises, there is no contract.

An example of a contract may look like this (I have to make up some syntax).

public interface Edible {

    public boolean isEdible();
    public boolean isEaten();
    public void eat() 
       precondition: isEdible();
       postcondition: isEaten();
    end

    invariant:
       isEaten() implies isEdible();
    end
}
$\endgroup$
7
  • $\begingroup$ To quote Oracle on Interfaces: "Interfaces form a contract between the class and the outside world, and this contract is enforced at build time by the compiler." So, it is a contract, in the sense of I'm talking about, which is what I'm asking about. Which is not exactly what you answered. Nevertheless, your comment on my example is useful. $\endgroup$
    – ItamarG3
    Jul 21, 2017 at 20:26
  • $\begingroup$ I think oracle (or was it sun micro-systems), read that interfaces form a contract, and then noted that they had something that they called an interface, and then wrongly concluded that they were constructing contracts. This is an easy mistake if they did not know what the original author meant by interface. “an interface is defined in terms of the obligations of the sender and the receiver involved in an interaction. … Typically these are set forth in preconditions and postconditions … invariant conditions.” — B.Meyers (1994) $\endgroup$ Jul 21, 2017 at 20:41
  • $\begingroup$ that may be. But do you agree that it can be thought of as a contract? $\endgroup$
    – ItamarG3
    Jul 21, 2017 at 20:43
  • $\begingroup$ @ItamarG3 If a Java interface is a contract, then. What do the two sides in the contract promise? I have around 25 years programming experience, and I can not see it. I would not expect my pupils to see it. Can you explain how Java interfaces are contracts to me. $\endgroup$ Jul 21, 2017 at 22:25
  • $\begingroup$ @richard, perhaps "intended contract" is a better term. It certainly can't be enforced in Java. But the software is generally better if everyone agrees to behave as if it were. $\endgroup$
    – Buffy
    Jul 23, 2017 at 11:05
1
$\begingroup$

An interface is an artifact that exists between two or more abstractions. It states what capabilities a given abstraction has to offer its users. It does not say how. The what part is an interface, and the how part is the implementation. A good interface is deep (the implementation has much more volume than the interface). Its a characteristic that makes it similar to a physical contract.

How does it correspond to an interface? You sign a six-page-long contract - that corresponds to a proportionally small interface of your abstraction. Then you provide your service or a product - that corresponds to a proportionally deep implementation hiding a lot of domain, and contract-specific complexity. The contract not only enforces mutual obligations but also gives you (as a service provider) a lot of freedom in execution, as long as you don’t breach the terms, and meet the essential KPIs.

As real-life contract - an interface is a basis for collaboration. I've written more about the topic here.

$\endgroup$
1
$\begingroup$

If I were asked to describe how a pin-and-tumbler lock works - the kind of lock most of the developed world have on their front doors - I cannot imagine that the word "contract" would find its way into the explanation.

This is despite the fact that, if you squint really hard, the relationship between the key (on the one hand) and the keyway and pins (on the other hand) does involve some kind of match, and the existence of the lock and key does in some sense govern the relationship between householder and strangers.

There's probably already a number of people who have no ready idea how pin-and-tumbler locks work to understand this analogy, and many more who would wonder where on Earth I pulled this from.

Likewise, many middle-age adults (let alone high school students) would have no clear idea what a "contract" even is, beyond some kind of lengthy document written in small print, that some corporation imposes on you as part of ordinary and necessary daily dealings in order to evade their legal liabilities.

Even if you ask a lawyer, they'd say a contract involves offer and acceptance, consideration on both sides, an intention to enter legal relations, and so on.

Does any of this seem to have the remotest connection to defining an "interface" in an OO programming language? I would say not.

I think that OO programming is actually very complicated to explain, both in computer science terms, and in terms of a certain philosophy or ideology that is associated with "pure" OO programming.

To add to the hassle, mainstream programming languages are a muddied synthesis of both OO concepts and non-OO concepts (with the non-OO concepts being something that don't reconcile with the OO concepts), and the most compelling demonstrations of the capabilities of OO programming involve software development being done at quite some scale with a division of labour (which is at odds with how most young programmers practice coding, which is as a solitary activity, and at odds with their industrial experience, which is zero).

Quite frankly, I would not even try to teach interfaces to high school students in terms of abstract concepts - unless you're dealing with a classroom of savants.

I would either just declare the concept to be something that is advanced beyond the level of your course, or I would demonstrate some practical examples of how interfaces can be used, without trying to explain their conceptual nature in a generalised fashion.

$\endgroup$
0
$\begingroup$

Rather than thinking of motivating examples, I prefer to teach it from the perspective of polymorphism. The mechanism of polymorphism requires an object referenced by a reference of the interface type to have a valid implementation of the method (and implementing the interface allows the compiler to enforce that requirement). So rather than teaching it as being merely a contract, I teach it as being part of a key mechanism in the Java programming language. I think it is important that students learn the underlying logic of a programming language and I think it is better to teach the principles rather than just presenting lots of examples and hoping the students will infer the mechanism for themselves (some will, some won't). Of course you need examples as well, to show the cool stuff you can do with the mechanism.

Of course this isn't the only use for interfaces, but it explains why the interface enforces a contract of sorts. Those other uses can be explained later, and when you do, the students will already understand that implementing an interface enforces a contract, so they can focus on the new use, rather than the mechanism.

$\endgroup$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.