Concepts / Interfaces in Java

Interfaces in Java

A functional interface is a Java file that holds a specification for exactly one subroutine, and it is defined in a .java file just as a class is.

  • Programming

Calling a Subroutine You Did Not Write

Imagine that someone else has written a subroutine and you want to call it. Before you write the call, you have to answer a few questions. What is the subroutine called? How many values does it expect you to pass in, and what type is each one? What type of value does it send back? If any of these answers is wrong, the call cannot be made correctly. The information that answers these questions is the subroutine's specification.

A functional interface is one way to write that specification down in a Java file. In this article you will learn what a functional interface records, how to read one, how to predict what its file contains, and how to locate the exact point where a call disagrees with the specification. Keep the calling picture in mind as you read: the question we are working toward is what a functional interface contains, and how you can tell from the code whether a use of it matches what it promises.

What a Specification Records

Definition

A functional interface is a Java file that holds a specification for exactly one subroutine. It is defined in a .java file just as a class is, and the file is named after the interface, as with any Java class.

The specification records three facts about that one subroutine. The first is its name. The second is its parameters, meaning how many there are and what type each one has. The third is its return type, which tells you what kind of value comes back to the caller.

Key point

The word one matters. A single functional interface describes a single subroutine. If you need to describe two different subroutines, you write two interfaces.

Reading the valueAt Declaration

The source's first example is a whole functional interface squeezed onto one line. It is saved in a file named FunctionR2R.java, which matches the name of the interface. The declaration is written out here as a single line inside the interface's braces:

java

Read it from left to right. The name of the interface is FunctionR2R. Inside the braces there is one line that names a subroutine, valueAt. That line lists one parameter, which has type double and is called x. The word double before valueAt is the return type. So the entire declaration says: there is a subroutine called valueAt, it takes one double, and it returns a double. The diagram below labels each part of the line.

doublereturn typevalueAtsubroutine name(double x)parameter list: one doublenamed x;no body follows
Where in this line of code is the subroutine's name, where are its parameters, where is its return type, and which part is missing because there is no body?

What do you think happens?

Before you check the declaration, predict: does the file contain code that computes how valueAt finds its answer, or only the shape of the call?

  • It contains the computation inside the braces

  • It contains only the shape of the call, with no computation

Reveal answer
Answer:

It contains only the shape of the call, with no computation

The declaration names the subroutine, lists its parameters, and gives its return type. If the file contained computation, you would expect to find it inside the braces. The braces hold only the one declaration line, and nothing computes the answer there.

Tracing the Declaration Line by Line

Once you can name each part of a declaration, you can trace the whole specification by walking through it in order. Work through the valueAt declaration this way, and use the result to decide what a caller must supply and what the caller will receive.

Worked example

Reading what a caller must supply

Using only the declaration interface FunctionR2R { double valueAt(double x); }, state what a caller must pass in and what the caller gets back.

  1. 1
    Find the name

    The subroutine is called valueAt, the word directly before the parenthesis.

  2. 2
    Count the parameters

    Inside the parentheses there is exactly one entry, so the subroutine takes one parameter.

  3. 3
    Check the parameter type

    That one parameter is declared as double, so the caller must pass one double value.

  4. 4
    Find the return type

    The word double before valueAt is the return type, so the caller receives one double value back.

Result

A caller must pass exactly one double and will receive a double back. The name used for the parameter, x, is not something the caller has to match.

A Second Shape: No Return Value

The source gives a second example with a different shape. It describes a subroutine that does not return anything and takes two parameters, an array of strings and an int. The source does not give this declaration a name, so the example below uses a placeholder name, printLines, to show the structure.

java

The two declarations have the same structure even though their contents differ. Each one names a single subroutine and then states its parameters and its return type. A return type of void is still a return type. It tells the caller that no value comes back. The shape never changes; only the values placed into it do. Here the parameters are a String array and an int, and the return type is void.

Finding Where a Call Diverges

Once you know the three facts, you can debug a broken use of a subroutine by asking where the use departs from the specification. Suppose some code calls valueAt with two numbers instead of one. The specification says there is one double parameter, so the mismatch is in the number of parameters. You do not need to guess; you compare the call against the declaration line by line, fact by fact.

valueAtnamevalueAtname used in callone doubleparameterstwo numbersarguments passeddoublereturn typedoublevalue expected backmatchesmismatch: countmatches
When a call passes the wrong number or types of arguments, or expects the wrong return type, which parts of the specification does it disagree with?
  • Common mistake

    Treating the parameter name as part of the contract

    What it looks like

    A call supplies a value to a parameter it believes is called something else.

    Why it fails

    The parameter name is written in the declaration but is not really part of the specification.

    Do this instead

    Compare the number of parameters and their types when checking a use.

  • Common mistake

    Expecting computation inside a functional interface

    What it looks like

    Looking inside the braces of the valueAt declaration for the arithmetic that produces its answer.

    Why it fails

    The file holds a specification only, and the declaration states the name, parameters, and return type without computing anything.

    Do this instead

    Expect the file to contain the shape of the subroutine, not the work it does.

  • Common mistake

    Checking only the name of the subroutine

    What it looks like

    Confirming that a call to valueAt is spelled correctly but ignoring that it passes two numbers.

    Why it fails

    The specification has three facts, and a call can match on the name while still disagreeing on parameters or return type.

    Do this instead

    Check the name, the parameters, and the return type, one at a time.

  • Common mistake

    Assuming one interface can describe two subroutines

Interface File Versus Class File

A functional interface holds the specification of a subroutine, while a class that provides the subroutine holds the working code for it. Opening the interface file, you should expect to find the name, the parameters, and the return type, and you should not expect to find a body that does the work. The table compares the two files for the valueAt subroutine.

Part of the subroutineFunctional interface fileClass file that implements it
Name (valueAt)PresentPresent
Parameters (one double)PresentPresent
Return type (double)PresentPresent
Working code that computes the answerAbsentPresent

What each file contains for the same subroutine

Checking Your Reading

MEDIUM

Take the declaration interface PrintLines { void printLines(String[] lines, int count); }. A teammate writes a call that passes one String array and then expects a double back. Name every fact of the specification that the call disagrees with, and state what you would change in the call to make it match.

Hints
  • Compare the call against the three facts: the name, the parameters, and the return type.
  • Count the arguments the call passes and compare them with the parameters listed in the declaration.
  • A void return type means no value comes back to the caller.

Key Takeaways

  • A functional interface is a Java file that holds a specification for exactly one subroutine, and it is defined in a .java file just as a class is.
  • The specification records three facts: the subroutine's name, its parameters (how many and their types), and its return type.
  • The parameter name appears in the declaration but is not really part of the specification, so compare parameter counts and types when checking a use.
  • A functional interface file holds the shape of the subroutine, not the computation; to find where a call diverges, compare it fact by fact against the declaration.