Abstract class vs interface in Java: what each one shares
Use one Java export example to compare interfaces and abstract classes: what callers can request, what objects inherit, and when neither needs a base class.
Use a Java interface to define operations that different kinds of objects must offer. Use an abstract class when related objects also need common fields, construction rules or implementation. A class can implement several interfaces but extend only one class.
A report and an image can both offer an export operation without being the same kind of object. Two kinds of report might also share a title field and the code that sets it. An interface can express the first promise; a base class can supply the second.
A download button needs bytes to send to the user. It should not need to know whether they came from a report or an image. Separately, several report classes might need the same title and the same construction rules. Those are two different reasons to share code or a type; one class can address both.
One export operation, two different jobs#
This illustrative example exports a plain-text report. The interface names the operation available to callers. The abstract class stores a title and leaves the report’s body for a subclass to provide.
import java.nio.charset.StandardCharsets;
import java.util.Objects;
interface Exportable {
byte[] export();
}
abstract class Report {
protected final String title;
protected Report(String title) {
this.title = Objects.requireNonNull(title);
}
protected abstract String body();
}
final class TextReport extends Report implements Exportable {
TextReport(String title) {
super(title);
}
@Override
protected String body() {
return "All systems ready.";
}
@Override
public byte[] export() {
return (title + "\n" + body()).getBytes(StandardCharsets.UTF_8);
}
}
Exportable lets the button call export() on any object that implements it. An image exporter could implement that interface without extending Report. The interface says that the operation returns bytes; it does not specify which file format those bytes contain.
Report does a different job. Each report object has its own title, set through the base constructor. A subclass supplies body(). TextReport combines the title and body and converts the text to UTF-8 bytes. This is actual text output, not a placeholder pretending to encode a PDF.
The example’s design is a choice, not a rule that every application needs a report hierarchy. It demonstrates what Java permits when the shared state is useful.
Sharing a field is also a decision about who may change it. A private field can still be exposed through a mutable object returned by a getter. The encapsulation guide’s two-seat Java example shows how to preserve a class’s rules and when to return a read-only view or a snapshot.
What can each one contain?#
| Question | Interface | Abstract class |
|---|---|---|
| Can one class use several? | It can implement several interfaces. | It can extend only one class. |
| Can it store fields separately for each object? | No. Its fields are public, static and final, not separate fields for each object. | Yes. |
| Can it have a constructor? | No. | Yes; a subclass calls it during construction. |
| Can it contain method bodies? | Yes: default, static and private methods. | Yes, alongside abstract methods. |
Can you create it directly with new? |
No. | No; create a concrete implementing class or subclass. |
These are Java rules, pinned here to the Java SE 25 interface specification and class specification. Other languages make different choices.
An interface default method supplies behaviour without supplying per-object fields. A private interface method can help other interface methods do their work; callers do not acquire it as a public operation. Neither feature turns an interface into an abstract class.
Choose what really needs to be shared#
Use an interface when callers need the same operation from otherwise different types. Use an abstract class when a group of related types benefits from the same fields and construction rules. Use both when those needs genuinely coexist, as in the example.
Sharing a few helper functions is not, by itself, a reason to make one class inherit from another. A separate helper object can supply that behaviour instead. That approach is called composition: an object uses another object rather than becoming its subclass.
The compiler checks that a concrete class supplies the required methods and respects their types. It cannot establish that an export contains the right report data. The compiler versus interpreter guide explains that boundary between build-time checks and runtime behaviour. Storing the resulting objects is another decision: single-table inheritance describes a database mapping, not a requirement imposed by extends.
Choose the relationship you need callers and subclasses to rely on. Do not introduce an inheritance hierarchy merely because two files currently contain similar code.
Questions people also ask
2 QUESTIONSCan a Java interface contain method implementations?
Yes. It can contain default, static and private methods. It cannot hold separate fields for each object or provide constructors. Interface fields are public, static and final.
Can an abstract class implement an interface?
Yes. It can supply some or all of the required methods. Any methods it leaves abstract must be implemented by a concrete subclass.