default, static and private methods since Java 8 and 9, and a class can implement as many as it likes. Choose an abstract class to share state and constructor logic inside one family; choose an interface to describe a capability that unrelated classes can have.
Versions. Every program on this page was compiled and run on JDK 25.0.4.1 (Temurin, LTS, build 25.0.4.1+1-LTS). Where Java 8 behaved differently the text says so. The compiler errors and console output are quoted verbatim from those runs; the “Download” links at the end of each section point to the exact .java files.
Abstract class vs interface: every difference in 12 rows
| # | Feature | Abstract class | Interface |
|---|---|---|---|
| 1 | Keyword | abstract class | interface |
| 2 | Can you create an object with new? | No (only via a concrete subclass or anonymous subclass) | No (only via an implementing class, anonymous class or lambda) |
| 3 | Instance fields (state) | Yes, any access level | No. Fields are implicitly public static final constants |
| 4 | Constructors | Yes; run when a subclass is created | No |
| 5 | Methods with a body | Yes, any kind | default, static (Java 8) and private (Java 9) |
| 6 | Abstract methods | Yes, must be marked abstract | Yes, implicitly public abstract |
| 7 | Member access levels | public, protected, package, private | Abstract/default/static are public; private helpers allowed |
| 8 | How many can a class use? | extends exactly one | implements any number |
| 9 | Lambda target | No | Yes, if it has exactly one abstract method (a functional interface) |
| 10 | Adding a method later | Safe if it has a body | Safe only as a default method; an abstract one breaks implementers |
| 11 | Sealing (sealed, Java 17) | Yes | Yes |
| 12 | Typical meaning | IS-A: a family sharing state and logic | CAN-DO: a capability or role |
Abstract class: shared state and a template method
An abstract class is the right tool when every subclass shares fields and a fixed algorithm with one or two variable steps. This is the template method pattern:abstract class Report {
protected final String title;
Report(String title) { this.title = title; System.out.println("Report constructor ran for " + title); }
abstract String body();
final String render() { return "== " + title + " ==\n" + body(); }
}
class CsvReport extends Report {
CsvReport(String t) { super(t); }
String body() { return "a,b,c"; }
}
Source: AbstractVsInterface.java. Report owns the title field and a constructor, declares body() abstract, and makes render() final so no subclass can change the overall shape. CsvReport supplies only the variable part.
$ java AbstractVsInterface.java
-- abstract class: state, constructor, template method --
Report constructor ran for sales
== sales ==
a,b,c
The first line proves row 4: the abstract class constructor ran when the subclass was created, so the abstract class really is part of the object. Compare that with an interface, which has no constructor to run. For how super(...) chaining works, see Constructors in Java.
Interface: default, static and private methods (Java 8 and 9)
Before Java 8 an interface could hold only abstract methods, so adding one broke every implementer. Java 8 addeddefault methods (a body that implementers inherit) and static methods, and Java 9 added private methods so defaults can share code without exposing it:
interface Greeter {
String name();
default String greet() { return decorate("Hi " + name()); }
static String shout(String s) { return s.toUpperCase() + "!"; }
private String decorate(String s) { return "[" + s + "]"; }
}
Source: AbstractVsInterface.java. Only name() is abstract, so Greeter is a functional interface; the anonymous class below needs to supply just that.
$ java AbstractVsInterface.java
-- interface: default, static, private methods --
[Hi Ankur]
HELLO!
[Hi Ankur] came from the default method calling the private helper. HELLO! came from the static method called on the interface name, not on an object. The reason Java added defaults at all was to evolve the standard library (collections gained forEach and stream) without breaking every class that already implemented them.
Interfaces still cannot hold instance state. A field in an interface is a constant, and trying to treat it as a variable is a compile error:
$ javac BrokenInterfaceState.java
BrokenInterfaceState.java:3: error: cannot assign a value to static final variable count
default void inc() { count++; }
^
1 error
Source: BrokenInterfaceState.java. This is row 3 in action: int count = 0; in an interface means public static final int count = 0;.
The diamond problem and how Java resolves it
Multiple inheritance of state is what Java forbids for classes. Multiple inheritance of behaviour is allowed through interface defaults, which reintroduces the “diamond”: two interfaces provide the same default method, and a class implements both.$ javac BrokenDiamond.java
BrokenDiamond.java:3: error: types A and B are incompatible;
class Both implements A, B { }
^
class Both inherits unrelated defaults for hello() from types A and B
1 error
Source: BrokenDiamond.java. The fix is to override and say which one you mean, with Interface.super.method():
interface A { default String hello() { return "A"; } }
interface B { default String hello() { return "B"; } }
class Both implements A, B {
@Override public String hello() { return A.super.hello() + "+" + B.super.hello(); }
}
$ java AbstractVsInterface.java
-- diamond: class must pick one --
A+B
A+B shows the class called both inherited versions explicitly. If one of the two interfaces were a class method instead, the class version would win without error; the explicit message is only for two defaults that tie.
Sealed interfaces (Java 17 and later)
Asealed interface lists exactly which types may implement it. That makes it a closed set, which lets the compiler check a switch for completeness without a default branch:
sealed interface Shape permits Circle, Square {}
record Circle(double r) implements Shape {}
record Square(double side) implements Shape {}
Source: AbstractVsInterface.java, where area is a switch over Shape with a case for each permitted record and no default.
$ java AbstractVsInterface.java
-- sealed interface + switch --
Circle area = 3.14
Square area = 4.00
If you later add a third permitted type, every such switch stops compiling until it handles it, which is the point: the compiler finds the places you forgot. sealed works on abstract classes too (row 11); the interface form is the common choice for closed families of records.
One class, many interfaces, one parent class
interface Flyer {}
interface Swimmer {}
class Animal {}
class Duck extends Animal implements Flyer, Swimmer {}
$ java AbstractVsInterface.java
-- one class, many interfaces; one parent class only --
[interface Flyer, interface Swimmer]
Duck superclass = Animal
Duck extends one class and implements two interfaces, which is the entire inheritance model in one line. It is also why interfaces describe abilities (Flyer, Swimmer) while the single superclass describes what the thing is.
When to choose which
| Situation | Pick |
|---|---|
| Subclasses need to share fields or constructor logic | Abstract class |
| You want a fixed algorithm with variable steps (template method) | Abstract class |
| Unrelated classes must share a capability (Comparable, Runnable, Closeable) | Interface |
| A class already extends another class and needs one more role | Interface (only option) |
| You want lambdas to implement it | Interface with one abstract method |
| You want a closed family the compiler can check | sealed interface (or abstract class) + records |
| Public library API you will evolve | Interface with default methods |
The standard interview answer to “why do both exist?” A class can extend only one class, so Java needed a way to say “this type can do X” without using up that single slot: that is the interface. But a contract alone cannot carry shared fields or constructor logic, so Java also keeps abstract classes for the case where related classes genuinely share state. Since Java 8 the gap has narrowed because interfaces can hold behaviour, but they still cannot hold instance state, and that is the line that never moved. The same “prefer composition and small contracts” reasoning is on the OOPs Concepts in Java page; the Collections framework is the best real example, withListas an interface andAbstractListas the skeleton class (see Top 40 Java Collections Interview Questions).
Download the code. AbstractVsInterface.java · BrokenDiamond.java · BrokenInterfaceState.java.
Run a runnable one withjava File.java(JDK 11 or later; JDK 25 recommended). Files starting withBrokenare meant to fail to compile.
Common interview questions
1. What is the difference between an abstract class and an interface?
An abstract class can have instance fields, constructors and any method bodies, and a class extends only one. An interface has no instance state, may have default, static and private methods, and a class can implement many. See the 12-row table above.
2. Can an abstract class have a constructor?
Yes. It cannot be called with new directly, but it runs when a concrete subclass is instantiated through super(...); the output above shows it running.
3. Can an interface have a constructor?
No. Interfaces have no instance state to initialise.
4. Can an interface have variables?
Only constants. Every field is implicitly public static final; assigning to it is a compile error.
5. What are default methods and why were they added?
Interface methods with a body, added in Java 8 so interfaces like Collection could gain new methods without breaking existing implementers.
6. Can an interface have static and private methods?
Yes: static since Java 8 (called on the interface name), private since Java 9 (shared helper code for default methods).
7. What is the diamond problem and how does Java handle it?
Two interfaces provide the same default method and a class implements both. The compiler rejects the class until it overrides the method, optionally calling A.super.m() and B.super.m().
8. Does Java support multiple inheritance?
Not of classes. A class extends one class but implements many interfaces, which gives multiple inheritance of type and of default behaviour, never of instance state.
9. Can an abstract class implement an interface without implementing its methods?
Yes. Because the abstract class cannot be instantiated, it can leave interface methods unimplemented for its concrete subclasses.
10. Can an abstract class be final?
No. final forbids extension and abstract requires it, so the combination is a compile error.
11. What is a functional interface?
An interface with exactly one abstract method, which a lambda or method reference can implement. @FunctionalInterface asks the compiler to check it.
12. What is a sealed interface?
An interface that names, with permits, the only types allowed to implement it. Combined with pattern-matching switch it gives compiler-checked completeness.
13. When would you choose an abstract class over an interface?
When subclasses share instance fields or constructor logic, or when you want a template method with a final skeleton; otherwise prefer an interface.
Common mistakes
- Using an abstract class just to share constants or helpers. A static utility or an interface constant block is lighter, and it does not use up your single
extendsslot. - Expecting state in an interface.
int count = 0;is a constant; incrementing it does not compile. - Forgetting to resolve conflicting defaults. Two interfaces with the same default method make the implementing class fail to compile until it overrides.
- Adding an abstract method to a published interface. Every implementer breaks. Add a
defaultmethod instead. - Calling an overridable method from an abstract class constructor. It can run before the subclass fields are set; see Flexible Constructor Bodies in Java 25 (JEP 513).
- Reaching for
extendsbecause it reuses code. If the relationship is not IS-A, use composition and an interface.
FAQ
What is the difference between abstract class and interface in Java?
An abstract class can hold instance state, constructors and implemented methods, and a class can extend only one. An interface defines a contract with no instance state, can have default, static and private methods, and a class can implement many.
When should I use an abstract class instead of an interface?
Use an abstract class when subclasses must share fields or constructor logic or follow a fixed template algorithm. Use an interface when you want to describe a capability that unrelated classes can have or when a class needs multiple roles.
Can an interface have a method body in Java 8 or later?
Yes. Java 8 added default and static methods with bodies, and Java 9 added private methods. Instance state is still not allowed.
Why does Java not support multiple inheritance of classes?
To avoid ambiguity about which parent field or method a subclass inherits. Interfaces give multiple inheritance of type and behaviour while avoiding multiple inheritance of state, and conflicting defaults must be resolved explicitly.
Has the difference between abstract class and interface changed in Java 25?
The core difference has not: interfaces still cannot hold instance state and abstract classes still can. Since Java 17 both can be sealed to restrict which classes may extend or implement them.
Where to go next
- OOPs Concepts in Java (the four pillars with a running example)
- Top 40 Java Collections Interview Questions (List, AbstractList and the interfaces behind the framework)
- Java Comparator and Comparable (Comparable and Comparator as interfaces in practice)
- Top 50 Java Stream API Coding Interview Questions (functional interfaces in action)
- Java Interview Preparation Guide
No Comments yet!