Abstract Methods in Java
A default method is a method with an implementation in an interface, marked with the default keyword, and classes that implement the interface can use it.
A Call to a Method the Class Never Writes
This article starts with code rather than a definition. The program below uses an interface called Readable and a class called Stars that implements it. Look at the main method first. It calls a method named readLine on a Stars object. The Stars class, as written here, does not define readLine anywhere. Your job in this article is to explain where readLine comes from and why the program still works.
****- Readable declares
readCharwith no body, so it is abstract - Readable provides a body for
readLinemarked with the default keyword - Stars writes
readCharand never writesreadLine - The Stars
readCharbody is an illustrative choice for this example: it returns a newline every fifth call and a star otherwise - main calls
stars.readLine(), which Stars does not define itself
What do you think happens?
When main calls stars.readLine(), which code body does Java use? Choose one before reading on.
Reveal answer
Java falls back to the body that the interface itself provides for readLine.
Stars does not define readLine, but readLine is a default method in Readable and has a body. Stars inherits that body, so the call compiles and runs. The loop inside readLine calls readChar once per character, which is why the second option is only partly true: readChar runs once per character, not readLine.
Tracing the readLine Call Step by Step
When main runs stars.readLine(), Java first looks for readLine in the Stars class. It does not find one there, so it uses the default body that Readable provides. That body creates an empty StringBuilder and then calls readChar for the first character. Each call to readChar goes to the Stars version, because Stars is the object on which the call was made. The loop keeps appending characters until readChar returns a line feed character, and then readLine returns the accumulated text.
Notice the two-way traffic in the diagram. The readLine body in Readable is the code that runs, but it keeps handing control back to Stars every time it needs a character. The line that main prints is therefore assembled by the interface code, while every individual character is produced by the class code. This split is what makes the rest of the article work.
Abstract and Default Methods Side by Side
A default method is a method with an implementation in an interface, marked with the default keyword. Classes that implement the interface can use it without writing their own version.
The keyword default appears in front of readLine in the interface. The syntax in the source is default public String readLine() followed by a body in braces. That body is the implementation that classes inherit when they do not provide their own. An interface method without a body, such as public char readChar(); in the same interface, is a different kind of method. It declares a required behavior but gives no code for it. Methods of this kind are the abstract methods the implementing class must supply.
The source describes the two kinds side by side in the Readable interface. readChar is the piece each implementing class must supply. readLine is built on top of readChar, and it is the piece the interface already supplies. This split is the central design idea of default methods: the interface can offer working behavior that depends on a method each class still has to write.
Why Stars Compiles Without Writing readLine
A class that implements an interface must provide an implementation for all abstract methods in that interface. In the Readable example, readChar has no body, so it is abstract, and Stars must write it. Stars does that with a body that returns a star most of the time and a newline otherwise. A class is not required to write default methods. Stars does not write readLine, but it is still allowed to call it, because readLine is a default method and the interface supplies its body.
Predicting whether a class compiles
A class implements Readable. It writes readChar but not readLine. Does it compile?
- 1Find the abstract methods
readCharhas no body in Readable, so it is abstract and the class must write it. - 2Check the class for readChar
The class writes
readChar, so the abstract requirement is met. - 3Check readLine
readLineis a default method with a body in Readable. The class does not need to override it. - 4Conclude
The only required method is written, so the class compiles.
The class compiles. Omitting a default method is allowed.
Debugging a Wrong Line of Output
Suppose the program prints a line that looks wrong. The line printed by main is built inside readLine, but each individual character is produced by readChar. If the printed line looks wrong, the fault could be in the loop inside the default method or in the character-producing code in Stars. You need to decide which by checking which method produced the value that went wrong.
Suppose the output shows a line that is too long, running past where a newline should have appeared. Start from main and work inward. main is correct to print whatever readLine returns, so the problem is inside readLine or below it. Check whether readLine stops when readChar returns a newline. If the loop is correct, the bad character must come from readChar, which is the frame that produced the value. In this case the fault is in the Stars version of readChar, not in the default body.
Mistakes Beginners Make With Default Methods
Common mistake Assuming a missing method means a compile error
What it looks likeStars does not define readLine, yet main calls stars.readLine().
Why it failsreadLineis a default method. The interface provides its body, so the call resolves to that body.Do this insteadCheck whether the method is abstract (no body) or default (body with the default keyword) before deciding whether the class must write it.
Common mistake Thinking every interface method must be written by the class
Why it failsOnly abstract methods must be implemented. Default methods are inherited with their bodies.
Do this insteadWrite only the abstract methods, such as readChar in this example.
Common mistake Blaming the default method for a bad character
What it looks likeA line is wrong, so the readLine loop is edited even though readChar produced the bad value.
Why it failsreadLineonly assembles characters. It cannot make a character thatreadChardoes not return.Do this insteadTrace which frame produced the first wrong value, then fix that method.
Practice: Classify, Predict, and Trace
Using the Readable program above, answer these three questions. First, list which methods in Readable are abstract and which are default. Second, if Stars were changed to remove readChar, would the class still compile, and why? Third, if the printed line is wrong only at its last character, which method should you inspect first, and why?
Hints
- Look for a body in braces. Methods with the default keyword have one.
- Ask which method a class is required to implement in Readable.
- Think about which method produces each character and which method decides when the line ends.
Key Takeaways
- A default method has an implementation in an interface, marked with the default keyword, and implementing classes can use it without writing it.
- An interface method without a body is abstract, and every implementing class must supply its own version.
- A call to a default method such as
stars.readLine()runs the interface body, which calls the class's abstract methods such asreadCharas needed. - When debugging, identify which method produced the first wrong value: the default method that assembles the result, or the abstract method that produces the raw values.