Interface vs Abstract Class — Core Differences
Fast recall
Quick revision
Core answer
Whether you can name the decisive differences (state, single vs multiple inheritance) and choose correctly.
Repeating outdated 'interfaces can't have method bodies' (false since Java 8) or missing the instance-state distinction.
Frame as IS-A shared base vs CAN-DO capability, note interfaces have only public static final constants (no instance variables), and that an interface can extend another interface.
Interview-ready guide
Interview answer
The cleanest way to separate them is by state, not by method bodies. An abstract class is a real class, so it can hold instance fields and a constructor and share concrete code — but you only get to extend one. An interface carries no per-object state; its fields are quietly public static final constants, and because nothing travels with it, a class can implement as many as it wants.
One thing I'd avoid is saying interfaces have no method bodies — that's been false since Java 8 gave them default and static methods. The real divide is instance state. I think of an abstract class as an IS-A shared base and an interface as a CAN-DO capability that even unrelated types can have — and an interface can even extend several other interfaces.
So my default is interface-first; I reach for an abstract class only when there's genuine shared state or code to inherit.
Interface vs Abstract Class — Core Differences
Direct Answer
An interface defines a type contract and can include abstract, default, static, and private methods, but it has no constructors or per-instance fields; its fields are public static final constants. An abstract class is a class that may hold instance state, constructors, and both abstract and concrete methods. A class can implement multiple interfaces but extend one class.
Code Example
// ── ABSTRACT CLASS: shared state + template ──────────────────────────────
abstract class Shape {
private final String color; // instance field — interfaces cannot hold per-instance fields
Shape(String color) { // constructor — interfaces have none
this.color = color;
}
String getColor() { return color; } // concrete shared method
abstract double area(); // each subclass must provide this
}
// ── INTERFACES: CAN-DO capabilities ──────────────────────────────────────
interface Drawable {
void draw(); // abstract method
default void render() { draw(); } // Java 8 default method — has a body
}
interface Resizable {
void resize(double factor);
}
// Interface constants: implicitly public static final
interface Config {
int MAX_SIDES = 100; // same as: public static final int MAX_SIDES = 100;
// int count; // ILLEGAL: no uninitialized fields in interfaces
}
// ── ONE CLASS: extends ONE abstract class, implements MANY interfaces ─────
class Circle extends Shape implements Drawable, Resizable, Config {
private double radius;
Circle(String color, double radius) {
super(color); // abstract class constructor called
this.radius = radius;
}
@Override
public double area() {
return Math.PI * radius * radius;
}
@Override
public void draw() {
System.out.println("Drawing " + getColor() + " circle, area=" + area());
}
@Override
public void resize(double factor) {
this.radius *= factor;
}
}
// ── INTERFACE EXTENDING INTERFACE ─────────────────────────────────────────
interface Readable { String read(); }
interface Writable { void write(String s); }
interface ReadWrite extends Readable, Writable { } // interface extends multiple interfaces
class FileStore implements ReadWrite {
public String read() { return "data"; }
public void write(String s) { /* persist */ }
}
// ── MAIN ──────────────────────────────────────────────────────────────────
public class Demo {
public static void main(String[] args) {
Circle c = new Circle("red", 5.0);
c.draw(); // Drawing red circle, area=78.53...
c.resize(2.0);
c.draw(); // area is now larger
System.out.println("Max sides constant: " + Config.MAX_SIDES); // 100
}
}
Common Mistakes & Pitfalls
- Saying 'interfaces can't have method bodies' — this has been false since Java 8 added
defaultandstaticmethods, and it instantly signals you learned Java from a pre-2014 article. - Treating interface fields as variables — every field is implicitly
public static final, so it's a shared constant; trying to use one as per-object state simply won't compile. - Thinking you must pick one or the other — a class can
extendone abstract class andimplementmany interfaces at the same time, and missing this leads to needlessly rigid designs. - Defaulting to an abstract class just to reuse code — that burns your single inheritance slot; when there's no shared instance state, an interface with
defaultmethods reuses code without the cost.
Check your understanding
Answer these without looking back at the article.
- Why can a class implement multiple interfaces but only extend one class?
- Can a class extend an abstract class and implement an interface simultaneously?
- How did Java 8 blur the line between interfaces and abstract classes?
Looking for a structured roadmap?
Every module on this page is also part of the full Java backend interview track.