7
$\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$
  • 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 '17 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 '17 at 7:20
  • $\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$ – ctrl-alt-delor Jul 21 '17 at 20:19
  • 2
    $\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 '18 at 13:17
  • 1
    $\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 '18 at 13:20
5
$\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$
  • $\begingroup$ The context of friendship sounds potentially useful. $\endgroup$ – ItamarG3 Jun 11 '17 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$ – cryptic_star Oct 13 '18 at 21:11
6
$\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$
  • $\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 '17 at 4:54
5
$\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$
  • $\begingroup$ I like the analogy, but I'm not sure it'll make it clear that implements I'd binding $\endgroup$ – ItamarG3 Jun 11 '17 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$ – Gypsy Spellweaver Jun 11 '17 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 '17 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$ – Sean Houlihane Jun 11 '17 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 '17 at 13:18
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$
  • $\begingroup$ interface specifically isn't about the user interface, it's about the object oriented programming interface. $\endgroup$ – ItamarG3 Jun 11 '17 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$ – Sean Houlihane Jun 11 '17 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 '18 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$ – Sean Houlihane Oct 18 '18 at 7:54
2
$\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$
  • $\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 '17 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 '17 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 '18 at 21:06
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$
  • $\begingroup$ This is an incredibly simple and very nice answer. Thank you! $\endgroup$ – ItamarG3 Oct 14 '18 at 7:52
  • $\begingroup$ @ItamarG3 It also is fun to see how much your students really have thought about the zombie apocalypse... :) $\endgroup$ – cryptic_star Oct 14 '18 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$
  • $\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 '17 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$ – ctrl-alt-delor Jul 21 '17 at 20:41
  • $\begingroup$ that may be. But do you agree that it can be thought of as a contract? $\endgroup$ – ItamarG3 Jul 21 '17 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$ – ctrl-alt-delor Jul 21 '17 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 '17 at 11:05

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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